From 2996035d5500656aa0757d3f6ebb5a2f36d958a1 Mon Sep 17 00:00:00 2001 From: li-strix <128799116+stevenaya@users.noreply.github.com> Date: Fri, 6 Nov 2026 19:24:40 +0900 Subject: [PATCH 1/3] Separate stable component keys from emitted link and joint names --- README.md | 2 + .../body/v2.0/config/inertials/nominal.yaml | 2 +- assets/body/v2.0/config/link/collisions.yaml | 2 +- assets/body/v2.0/config/link/visuals.yaml | 2 +- .../v2.0/config/struct/reference_points.yaml | 10 ++-- assets/body/v2.0/config/struct/topology.yaml | 3 +- assets/common/assembly.xacro | 8 +-- assets/common/components.xacro | 14 ++++-- assets/common/kinematic_chain.xacro | 24 +++++---- assets/common/links.xacro | 2 +- assets/common/validation.xacro | 12 +++-- .../config/inertials/nominal.yaml | 6 +-- .../config/joint/joint_axes.yaml | 4 +- .../config/joint/joint_limits.yaml | 4 +- .../config/joint/joint_mimics.yaml | 4 +- .../config/joint/joint_origins.yaml | 4 +- .../pinch_gripper/config/link/collisions.yaml | 6 +-- .../pinch_gripper/config/link/visuals.yaml | 6 +-- .../config/struct/name_mapping.yaml | 20 ++++---- .../config/struct/reference_points.yaml | 6 +-- .../pinch_gripper/config/struct/topology.yaml | 23 +++++---- .../pinch_gripper/urdf/component.xacro | 2 + .../urdf/pinch_gripper_macro.xacro | 35 ++++++------- .../config/arm/inertials/nominal.yaml | 14 +++--- .../config/arm/link/collisions.yaml | 14 +++--- .../openarm_v2.0/config/arm/link/visuals.yaml | 14 +++--- .../config/arm/struct/name_mapping.yaml | 32 ++++++------ .../config/arm/struct/reference_points.yaml | 4 +- .../config/arm/struct/topology.yaml | 43 +++++++++------- .../robot_presets/default_bimanual.yaml | 2 +- .../config/robot_presets/left_arm.yaml | 2 +- .../left_arm_with_pinch_gripper.yaml | 2 +- .../openarm_v2.0/urdf/openarm_v20.urdf.xacro | 2 +- assets/sensor/zed/urdf/component.xacro | 5 +- test/support.py | 17 ++++--- test/test_assembly.py | 50 ++++++++++++------- test/test_entrypoints.py | 8 +-- 37 files changed, 230 insertions(+), 180 deletions(-) diff --git a/README.md b/README.md index 15c33176..7f82e7cf 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,8 @@ The default implementations are `openarm_describe_config_component` and `openarm Interface files declare macros; implementation and third-party model includes belong inside those macros. Each interface is loaded in a local scope, so its definitions do not affect other components. Presets need no implementation selector or product registry. +Component topology uses stable `link1`, `link2`, ... and `joint1`, `joint2`, ... keys. An optional `name` on each topology entry defines its local URDF name; otherwise the key is used. The instance prefix is added once. Geometry, inertia, joint parameters, parent/child links, mimic targets, references, reflection selections and overrides use the stable keys. Changing `name` preserves these config references. Component descriptors expose resolved `link_name_map` and `joint_name_map` entries for emitters and control generation. + ## Related links - 📚 Read the [documentation](https://docs.openarm.dev/software/description) diff --git a/assets/body/v2.0/config/inertials/nominal.yaml b/assets/body/v2.0/config/inertials/nominal.yaml index 75949159..52fdec86 100644 --- a/assets/body/v2.0/config/inertials/nominal.yaml +++ b/assets/body/v2.0/config/inertials/nominal.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -body_link0: +link1: origin: x: -0.01627169562 y: 0.0 diff --git a/assets/body/v2.0/config/link/collisions.yaml b/assets/body/v2.0/config/link/collisions.yaml index 46fb7013..7e1d776d 100644 --- a/assets/body/v2.0/config/link/collisions.yaml +++ b/assets/body/v2.0/config/link/collisions.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -body_link0: +link1: origin: x: 0.0 y: 0.0 diff --git a/assets/body/v2.0/config/link/visuals.yaml b/assets/body/v2.0/config/link/visuals.yaml index f1fa731c..474ec659 100644 --- a/assets/body/v2.0/config/link/visuals.yaml +++ b/assets/body/v2.0/config/link/visuals.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -body_link0: +link1: origin: x: 0.0 y: 0.0 diff --git a/assets/body/v2.0/config/struct/reference_points.yaml b/assets/body/v2.0/config/struct/reference_points.yaml index bf695c6c..38e13a41 100644 --- a/assets/body/v2.0/config/struct/reference_points.yaml +++ b/assets/body/v2.0/config/struct/reference_points.yaml @@ -13,7 +13,7 @@ # limitations under the License. left_arm_mount_point: - parent: body_link0 + parent: link1 origin: x: 0.0 y: 0.030 @@ -29,13 +29,13 @@ left_arm_mount_point: type: fixed parent_link: original_name: body_link0 - canonical_name: body_link0 + canonical_name: link1 child_link: original_name: body_left_arm_mount_point canonical_name: null right_arm_mount_point: - parent: body_link0 + parent: link1 origin: x: 0.0 y: -0.030 @@ -51,13 +51,13 @@ right_arm_mount_point: type: fixed parent_link: original_name: body_link0 - canonical_name: body_link0 + canonical_name: link1 child_link: original_name: body_right_arm_mount_point canonical_name: null arm_origin: - parent: body_link0 + parent: link1 emit: true origin: x: 0.0 diff --git a/assets/body/v2.0/config/struct/topology.yaml b/assets/body/v2.0/config/struct/topology.yaml index 59402442..97b46d61 100644 --- a/assets/body/v2.0/config/struct/topology.yaml +++ b/assets/body/v2.0/config/struct/topology.yaml @@ -13,5 +13,6 @@ # limitations under the License. links: - - body_link0 + link1: + name: body_link0 joints: {} diff --git a/assets/common/assembly.xacro b/assets/common/assembly.xacro index c67a42ac..e24c8c6a 100644 --- a/assets/common/assembly.xacro +++ b/assets/common/assembly.xacro @@ -96,7 +96,7 @@ limitations under the License. - + @@ -111,9 +111,9 @@ limitations under the License. - + @@ -123,7 +123,7 @@ limitations under the License. name="attached_children" value="${[name for name in components if name in robot_preset and robot_preset[name]['enabled'] and 'connection' in robot_preset[name] and 'attach_to' in robot_preset[name]['connection'] and robot_preset[name]['connection']['attach_to'] == component_name]}" lazy_eval="false" /> - + - - - - + + + + + + params="index joint_names topology prefix link_name_map joint_name_map joint_origins joint_axes joint_limits joint_mimics inertials visuals collisions reflect_x reflect_y reflect_z reflect_include_links reflect_include_joints origin_override_joints limit_override_joints tip_collapse_source_link tip_collapse_child_link base_frame_shift"> @@ -26,20 +26,21 @@ limitations under the License. - - + frame_shift="${base_frame_shift if joint['parent'] == list(topology['links'])[0] else 'none'}" /> + params="connected_to mount_origin topology prefix link_name_map joint_name_map joint_origins joint_axes joint_limits joint_mimics:=${dict()} inertials visuals collisions reflect_x:=1 reflect_y:=1 reflect_z:=1 reflect_include_links:=${[]} reflect_include_joints:=${[]} origin_override_joints:=${dict()} limit_override_joints:=${dict()} tip_collapse_source_link:=none tip_collapse_child_link:=none skip_mount_joint:=${False} base_frame_shift:=none"> - + - - + - + - + diff --git a/assets/common/validation.xacro b/assets/common/validation.xacro index e772915c..5bcee7d5 100644 --- a/assets/common/validation.xacro +++ b/assets/common/validation.xacro @@ -137,7 +137,7 @@ limitations under the License. - + @@ -146,10 +146,16 @@ limitations under the License. - + - + + + + + diff --git a/assets/end_effector/pinch_gripper/config/inertials/nominal.yaml b/assets/end_effector/pinch_gripper/config/inertials/nominal.yaml index 6bfd2f4b..05ebfae2 100644 --- a/assets/end_effector/pinch_gripper/config/inertials/nominal.yaml +++ b/assets/end_effector/pinch_gripper/config/inertials/nominal.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -ee_base_link: +link1: origin: x: -0.0067098 y: 0.008407299999999999 @@ -28,7 +28,7 @@ ee_base_link: yy: 0.00015627 yz: -1.5124e-06 zz: 0.0001659 -ee_link1: +link2: origin: x: -0.0124990911725494 y: 0.00176592789915655 @@ -44,7 +44,7 @@ ee_link1: yy: 3.62137424319396e-05 yz: -3.60343788693423e-06 zz: 1.74958961632907e-05 -ee_link2: +link3: origin: x: -0.012796 y: -0.0020183 diff --git a/assets/end_effector/pinch_gripper/config/joint/joint_axes.yaml b/assets/end_effector/pinch_gripper/config/joint/joint_axes.yaml index 13cc0ae1..c8d738fa 100644 --- a/assets/end_effector/pinch_gripper/config/joint/joint_axes.yaml +++ b/assets/end_effector/pinch_gripper/config/joint/joint_axes.yaml @@ -12,12 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -finger_joint1: +joint1: axis: x: -1 y: 0 z: 0 -finger_joint2: +joint2: axis: x: 1 y: 0 diff --git a/assets/end_effector/pinch_gripper/config/joint/joint_limits.yaml b/assets/end_effector/pinch_gripper/config/joint/joint_limits.yaml index 19942211..8dfc86de 100644 --- a/assets/end_effector/pinch_gripper/config/joint/joint_limits.yaml +++ b/assets/end_effector/pinch_gripper/config/joint/joint_limits.yaml @@ -12,13 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -finger_joint1: +joint1: limit: lower: -0.7854 upper: 0 effort: 7 velocity: 5 -finger_joint2: +joint2: limit: lower: -0.7854 upper: 0 diff --git a/assets/end_effector/pinch_gripper/config/joint/joint_mimics.yaml b/assets/end_effector/pinch_gripper/config/joint/joint_mimics.yaml index 1c0f9656..48434cde 100644 --- a/assets/end_effector/pinch_gripper/config/joint/joint_mimics.yaml +++ b/assets/end_effector/pinch_gripper/config/joint/joint_mimics.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -finger_joint2: - joint: finger_joint1 +joint2: + joint: joint1 multiplier: 1 offset: 0 diff --git a/assets/end_effector/pinch_gripper/config/joint/joint_origins.yaml b/assets/end_effector/pinch_gripper/config/joint/joint_origins.yaml index cc5b65bf..da58c50f 100644 --- a/assets/end_effector/pinch_gripper/config/joint/joint_origins.yaml +++ b/assets/end_effector/pinch_gripper/config/joint/joint_origins.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -finger_joint1: +joint1: origin: x: -0.0219300000000005 y: 0.0180000000000009 @@ -20,7 +20,7 @@ finger_joint1: roll: 0 pitch: -0 yaw: 0 -finger_joint2: +joint2: origin: x: -0.0219300000000005 y: -0.0180000000000012 diff --git a/assets/end_effector/pinch_gripper/config/link/collisions.yaml b/assets/end_effector/pinch_gripper/config/link/collisions.yaml index 2dfa0c8e..1f4d4c1b 100644 --- a/assets/end_effector/pinch_gripper/config/link/collisions.yaml +++ b/assets/end_effector/pinch_gripper/config/link/collisions.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -ee_base_link: +link1: origin: x: 0 y: 0 @@ -26,7 +26,7 @@ ee_base_link: x: 1 y: 1 z: 1 -ee_link1: +link2: origin: x: 0 y: 0 @@ -40,7 +40,7 @@ ee_link1: x: 1 y: 1 z: 1 -ee_link2: +link3: origin: x: 0 y: 0 diff --git a/assets/end_effector/pinch_gripper/config/link/visuals.yaml b/assets/end_effector/pinch_gripper/config/link/visuals.yaml index d6669034..144aca0d 100644 --- a/assets/end_effector/pinch_gripper/config/link/visuals.yaml +++ b/assets/end_effector/pinch_gripper/config/link/visuals.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -ee_base_link: +link1: origin: x: 0 y: 0 @@ -26,7 +26,7 @@ ee_base_link: x: 1 y: 1 z: 1 -ee_link1: +link2: origin: x: 0 y: 0 @@ -40,7 +40,7 @@ ee_link1: x: 1 y: 1 z: 1 -ee_link2: +link3: origin: x: 0 y: 0 diff --git a/assets/end_effector/pinch_gripper/config/struct/name_mapping.yaml b/assets/end_effector/pinch_gripper/config/struct/name_mapping.yaml index 84555f5c..b6300337 100644 --- a/assets/end_effector/pinch_gripper/config/struct/name_mapping.yaml +++ b/assets/end_effector/pinch_gripper/config/struct/name_mapping.yaml @@ -14,17 +14,17 @@ links: canonical_to_original: - ee_base_link: ee_base_link - ee_link1: finger_inner - ee_link2: finger_outer + link1: ee_base_link + link2: finger_inner + link3: finger_outer original_to_canonical: - ee_base_link: ee_base_link - finger_inner: ee_link1 - finger_outer: ee_link2 + ee_base_link: link1 + finger_inner: link2 + finger_outer: link3 joints: canonical_to_original: - finger_joint1: finger_inner_joint - finger_joint2: finger_outer_joint + joint1: finger_inner_joint + joint2: finger_outer_joint original_to_canonical: - finger_inner_joint: finger_joint1 - finger_outer_joint: finger_joint2 + finger_inner_joint: joint1 + finger_outer_joint: joint2 diff --git a/assets/end_effector/pinch_gripper/config/struct/reference_points.yaml b/assets/end_effector/pinch_gripper/config/struct/reference_points.yaml index e3cbf358..51344d31 100644 --- a/assets/end_effector/pinch_gripper/config/struct/reference_points.yaml +++ b/assets/end_effector/pinch_gripper/config/struct/reference_points.yaml @@ -13,7 +13,7 @@ # limitations under the License. grasp_frame: - parent: ee_base_link + parent: link1 origin: x: -0.0219300000000009 y: 0 @@ -29,13 +29,13 @@ grasp_frame: type: fixed parent_link: original_name: ee_base_link - canonical_name: ee_base_link + canonical_name: link1 child_link: original_name: grasp_frame canonical_name: null camera_view_frame: - parent: ee_base_link + parent: link1 emit: true origin: x: 0.0013353 diff --git a/assets/end_effector/pinch_gripper/config/struct/topology.yaml b/assets/end_effector/pinch_gripper/config/struct/topology.yaml index 9b3784e2..ff2863cb 100644 --- a/assets/end_effector/pinch_gripper/config/struct/topology.yaml +++ b/assets/end_effector/pinch_gripper/config/struct/topology.yaml @@ -13,15 +13,20 @@ # limitations under the License. links: -- ee_base_link -- ee_link1 -- ee_link2 + link1: + name: ee_base_link + link2: + name: ee_link1 + link3: + name: ee_link2 joints: - finger_joint1: + joint1: + name: finger_joint1 type: revolute - parent: ee_base_link - child: ee_link1 - finger_joint2: + parent: link1 + child: link2 + joint2: + name: finger_joint2 type: revolute - parent: ee_base_link - child: ee_link2 + parent: link1 + child: link3 diff --git a/assets/end_effector/pinch_gripper/urdf/component.xacro b/assets/end_effector/pinch_gripper/urdf/component.xacro index 4c130677..62f9ea4a 100644 --- a/assets/end_effector/pinch_gripper/urdf/component.xacro +++ b/assets/end_effector/pinch_gripper/urdf/component.xacro @@ -28,6 +28,8 @@ limitations under the License. + params="prefix connected_to mount_origin:=none topology link_name_map joint_name_map joint_origins joint_axes joint_limits joint_mimics inertials visuals collisions reflect_x:=1 reflect_y:=1 reflect_z:=1 component_reflects:=false reflect_include_links:=^ reflect_include_joints:=^ reflect_include_reference_points:=^ origin_override_joints:=${dict()} limit_override_joints:=^ ee_reference_points:=^ emit_grasp_frame:=false grasp_reference_point:=grasp_frame skip_mount_joint:=false base_frame_shift:=none"> - + - + - - - - + + + + @@ -44,8 +44,8 @@ limitations under the License. - - + + - + - - + + @@ -139,15 +139,15 @@ limitations under the License. - + - - + + @@ -164,6 +164,7 @@ limitations under the License. reference_points="${ee_reference_points}" force_emit_reference="${grasp_reference_point if emit_grasp_frame else ''}" prefix="${prefix}" + link_name_map="${link_name_map}" base_link_name="${base_link_name}" reflect_x="${reflect_x if component_reflects else 1}" reflect_y="${reflect_y if component_reflects else 1}" diff --git a/assets/robot/openarm_v2.0/config/arm/inertials/nominal.yaml b/assets/robot/openarm_v2.0/config/arm/inertials/nominal.yaml index a6f5f7ec..6d7df71d 100644 --- a/assets/robot/openarm_v2.0/config/arm/inertials/nominal.yaml +++ b/assets/robot/openarm_v2.0/config/arm/inertials/nominal.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -base_link: +link1: origin: x: 0.00253123748061566 y: -0.0258185540330169 @@ -28,7 +28,7 @@ base_link: yy: 0.00159935208714031 yz: 2.7521421737084e-08 zz: 0.000750541980863571 -link1: +link2: origin: x: 0.000900350355624244 y: -0.0444659716892874 @@ -44,7 +44,7 @@ link1: yy: 0.000759199728161993 yz: 6.66755698859637e-08 zz: 0.000670659201019629 -link2: +link3: origin: x: -0.0247184924346635 y: 7.60578399428002e-08 @@ -60,7 +60,7 @@ link2: yy: 0.000113062180225725 yz: 3.75816911469744e-10 zz: 8.22999351863579e-05 -link3: +link4: origin: x: -0.00300861804638783 y: -0.000514813312550808 @@ -76,7 +76,7 @@ link3: yy: 0.00114018992179734 yz: -1.06260802872572e-05 zz: 0.000559765478676303 -link4: +link5: origin: x: -0.00310326243752606 y: -0.00136538979048502 @@ -92,7 +92,7 @@ link4: yy: 0.000433926270522842 yz: 3.41757797773822e-06 zz: 0.000245211429759716 -link5: +link6: origin: x: -0.000737188580130584 y: -0.000412406544351845 @@ -108,7 +108,7 @@ link5: yy: 0.000334599623120095 yz: -1.49934409279756e-07 zz: 0.000176662464388138 -link6: +link7: origin: x: 2.27438423593244e-05 y: 0.00068649602098908 diff --git a/assets/robot/openarm_v2.0/config/arm/link/collisions.yaml b/assets/robot/openarm_v2.0/config/arm/link/collisions.yaml index 288633ba..4980bbc4 100644 --- a/assets/robot/openarm_v2.0/config/arm/link/collisions.yaml +++ b/assets/robot/openarm_v2.0/config/arm/link/collisions.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -base_link: +link1: origin: x: 0 y: 0 @@ -26,7 +26,7 @@ base_link: x: 1 y: 1 z: 1 -link1: +link2: origin: x: 0 y: 0 @@ -40,7 +40,7 @@ link1: x: 1 y: 1 z: 1 -link2: +link3: origin: x: 0 y: 0 @@ -54,7 +54,7 @@ link2: x: 1 y: 1 z: 1 -link3: +link4: origin: x: 0 y: 0 @@ -68,7 +68,7 @@ link3: x: 1 y: 1 z: 1 -link4: +link5: origin: x: 0 y: 0 @@ -82,7 +82,7 @@ link4: x: 1 y: 1 z: 1 -link5: +link6: origin: x: 0 y: 0 @@ -96,7 +96,7 @@ link5: x: 1 y: 1 z: 1 -link6: +link7: origin: x: 0 y: 0 diff --git a/assets/robot/openarm_v2.0/config/arm/link/visuals.yaml b/assets/robot/openarm_v2.0/config/arm/link/visuals.yaml index 6fcf1682..9e6a8467 100644 --- a/assets/robot/openarm_v2.0/config/arm/link/visuals.yaml +++ b/assets/robot/openarm_v2.0/config/arm/link/visuals.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -base_link: +link1: origin: x: 0 y: 0 @@ -26,7 +26,7 @@ base_link: x: 1 y: 1 z: 1 -link1: +link2: origin: x: 0 y: 0 @@ -40,7 +40,7 @@ link1: x: 1 y: 1 z: 1 -link2: +link3: origin: x: 0 y: 0 @@ -54,7 +54,7 @@ link2: x: 1 y: 1 z: 1 -link3: +link4: origin: x: 0 y: 0 @@ -68,7 +68,7 @@ link3: x: 1 y: 1 z: 1 -link4: +link5: origin: x: 0 y: 0 @@ -82,7 +82,7 @@ link4: x: 1 y: 1 z: 1 -link5: +link6: origin: x: 0 y: 0 @@ -96,7 +96,7 @@ link5: x: 1 y: 1 z: 1 -link6: +link7: origin: x: 0 y: 0 diff --git a/assets/robot/openarm_v2.0/config/arm/struct/name_mapping.yaml b/assets/robot/openarm_v2.0/config/arm/struct/name_mapping.yaml index 98d02fd9..dbabebb3 100644 --- a/assets/robot/openarm_v2.0/config/arm/struct/name_mapping.yaml +++ b/assets/robot/openarm_v2.0/config/arm/struct/name_mapping.yaml @@ -14,23 +14,23 @@ links: canonical_to_original: - base_link: base_link - link1: link1 - link2: link2 - link3: link3 - link4: link4 - link5: link5 - link6: link6 - link7: empty_link_for_J7 + link1: base_link + link2: link1 + link3: link2 + link4: link3 + link5: link4 + link6: link5 + link7: link6 + link8: empty_link_for_J7 original_to_canonical: - base_link: base_link - link1: link1 - link2: link2 - link3: link3 - link4: link4 - link5: link5 - link6: link6 - empty_link_for_J7: link7 + base_link: link1 + link1: link2 + link2: link3 + link3: link4 + link4: link5 + link5: link6 + link6: link7 + empty_link_for_J7: link8 joints: canonical_to_original: joint1: joint1 diff --git a/assets/robot/openarm_v2.0/config/arm/struct/reference_points.yaml b/assets/robot/openarm_v2.0/config/arm/struct/reference_points.yaml index 2f524870..1cd09d60 100644 --- a/assets/robot/openarm_v2.0/config/arm/struct/reference_points.yaml +++ b/assets/robot/openarm_v2.0/config/arm/struct/reference_points.yaml @@ -13,7 +13,7 @@ # limitations under the License. ee_mount_point: - parent: link7 + parent: link8 origin: x: 0.0205 y: 0 @@ -29,7 +29,7 @@ ee_mount_point: type: fixed parent_link: original_name: empty_link_for_J7 - canonical_name: link7 + canonical_name: link8 child_link: original_name: empty_link_for_ee_mounting canonical_name: null diff --git a/assets/robot/openarm_v2.0/config/arm/struct/topology.yaml b/assets/robot/openarm_v2.0/config/arm/struct/topology.yaml index acd91f4b..f2f248e3 100644 --- a/assets/robot/openarm_v2.0/config/arm/struct/topology.yaml +++ b/assets/robot/openarm_v2.0/config/arm/struct/topology.yaml @@ -13,42 +13,49 @@ # limitations under the License. collapse_empty_end: true - links: - - base_link - - link1 - - link2 - - link3 - - link4 - - link5 - - link6 - - link7 + link1: + name: base_link + link2: + name: link1 + link3: + name: link2 + link4: + name: link3 + link5: + name: link4 + link6: + name: link5 + link7: + name: link6 + link8: + name: link7 joints: joint1: - type: revolute - parent: base_link - child: link1 - joint2: type: revolute parent: link1 child: link2 - joint3: + joint2: type: revolute parent: link2 child: link3 - joint4: + joint3: type: revolute parent: link3 child: link4 - joint5: + joint4: type: revolute parent: link4 child: link5 - joint6: + joint5: type: revolute parent: link5 child: link6 - joint7: + joint6: type: revolute parent: link6 child: link7 + joint7: + type: revolute + parent: link7 + child: link8 diff --git a/assets/robot/openarm_v2.0/config/robot_presets/default_bimanual.yaml b/assets/robot/openarm_v2.0/config/robot_presets/default_bimanual.yaml index 3771f40b..2a18cc1b 100644 --- a/assets/robot/openarm_v2.0/config/robot_presets/default_bimanual.yaml +++ b/assets/robot/openarm_v2.0/config/robot_presets/default_bimanual.yaml @@ -60,7 +60,7 @@ primary_arm: y: -1 z: 1 include: - links: [base_link, link1, link2, link5, link6, link7] + links: [link1, link2, link3, link6, link7, link8] joints: [joint1, joint2, joint3, joint5, joint6, joint7] reference_points: [ee_mount_point] limit_override_joints: {} diff --git a/assets/robot/openarm_v2.0/config/robot_presets/left_arm.yaml b/assets/robot/openarm_v2.0/config/robot_presets/left_arm.yaml index 2b94a8ae..66f1af6e 100644 --- a/assets/robot/openarm_v2.0/config/robot_presets/left_arm.yaml +++ b/assets/robot/openarm_v2.0/config/robot_presets/left_arm.yaml @@ -60,7 +60,7 @@ primary_arm: y: -1 z: 1 include: - links: [base_link, link1, link2, link5, link6, link7] + links: [link1, link2, link3, link6, link7, link8] joints: [joint1, joint2, joint3, joint5, joint6, joint7] reference_points: [ee_mount_point] limit_override_joints: {} diff --git a/assets/robot/openarm_v2.0/config/robot_presets/left_arm_with_pinch_gripper.yaml b/assets/robot/openarm_v2.0/config/robot_presets/left_arm_with_pinch_gripper.yaml index fbfa0663..b7146b04 100644 --- a/assets/robot/openarm_v2.0/config/robot_presets/left_arm_with_pinch_gripper.yaml +++ b/assets/robot/openarm_v2.0/config/robot_presets/left_arm_with_pinch_gripper.yaml @@ -61,7 +61,7 @@ primary_arm: y: -1 z: 1 include: - links: [base_link, link1, link2, link5, link6, link7] + links: [link1, link2, link3, link6, link7, link8] joints: [joint1, joint2, joint3, joint5, joint6, joint7] reference_points: [ee_mount_point] limit_override_joints: {} diff --git a/assets/robot/openarm_v2.0/urdf/openarm_v20.urdf.xacro b/assets/robot/openarm_v2.0/urdf/openarm_v20.urdf.xacro index 351b2678..ed37d4a9 100644 --- a/assets/robot/openarm_v2.0/urdf/openarm_v20.urdf.xacro +++ b/assets/robot/openarm_v2.0/urdf/openarm_v20.urdf.xacro @@ -39,7 +39,7 @@ limitations under the License. - + Date: Fri, 6 Nov 2026 19:24:41 +0900 Subject: [PATCH 2/3] Declare control systems using component keys and stable joint indices --- README.md | 2 + assets/common/assembly.xacro | 59 +++---- assets/common/ros2_control.xacro | 129 ++++++++++++++ assets/component_loader.xacro | 3 +- .../robot_presets/default_bimanual.yaml | 26 +++ .../config/robot_presets/left_arm.yaml | 12 ++ .../left_arm_with_pinch_gripper.yaml | 14 ++ .../config/robot_presets/right_arm.yaml | 12 ++ .../right_arm_with_pinch_gripper.yaml | 14 ++ .../robot/openarm_v2.0/urdf/example/v2.urdf | 16 -- .../openarm_v2.0/urdf/openarm_v20.urdf.xacro | 46 ++--- .../openarm.bimanual.ros2_control.xacro | 157 ----------------- .../ros2_control/openarm.ros2_control.xacro | 107 ------------ launch/display_openarm.launch.py | 5 +- test/support.py | 11 -- test/test_interfaces.py | 161 ++++++++++++++++++ test/test_models.py | 43 +++++ 17 files changed, 465 insertions(+), 352 deletions(-) create mode 100644 assets/common/ros2_control.xacro delete mode 100644 assets/robot/openarm_v2.0/urdf/ros2_control/openarm.bimanual.ros2_control.xacro delete mode 100644 assets/robot/openarm_v2.0/urdf/ros2_control/openarm.ros2_control.xacro create mode 100644 test/test_models.py diff --git a/README.md b/README.md index 7f82e7cf..65483f8c 100644 --- a/README.md +++ b/README.md @@ -51,3 +51,5 @@ Copyright 2025 Enactic, Inc. All participation in the OpenArm project is governed by our [Code of Conduct](CODE_OF_CONDUCT.md). + +Control partitions are declared under the preset's top-level `systems` mapping. Each system's `joints` maps component instance names to stable local joint keys with an `idx`. Each active joint requires a unique non-negative integer `idx` within its system; gaps are allowed. Joints are emitted in index order, with `idx` included as a joint parameter for runtime adapters. Disabled components are skipped, and final joint names come from the resolved component descriptions. Standard OpenArm hardware defaults are supplied by the model entry. Per-system hardware_plugin and driver parameters can override those defaults, and CAN launch arguments take precedence. `use_fake_hardware:=true` selects `mock_components/GenericSystem`. Optional `command_interfaces` and `state_interfaces` default to `[position, velocity, effort]`. diff --git a/assets/common/assembly.xacro b/assets/common/assembly.xacro index e24c8c6a..1398db64 100644 --- a/assets/common/assembly.xacro +++ b/assets/common/assembly.xacro @@ -16,23 +16,21 @@ limitations under the License. - + - - - - + + - + + params="component_descriptions component_name components robot_preset config_root root_frame component_cfg component_desc parent_desc:=none emit_grasp_frame:=false out_name"> @@ -133,8 +131,9 @@ limitations under the License. value="${[name for name in attached_children if component_terminal_link_empty and 'parent_reference_point' in robot_preset[name]['connection'] and robot_preset[name]['connection']['parent_reference_point'] != None and ('parent' not in robot_preset[name]['connection'] or robot_preset[name]['connection']['parent'] == None) and robot_preset[name]['connection']['parent_reference_point'] in component_desc['reference_points'] and component_desc['reference_points'][robot_preset[name]['connection']['parent_reference_point']]['parent'] == component_terminal_link]}" lazy_eval="false" /> - + @@ -169,20 +168,12 @@ limitations under the License. + params="component_api component_descriptions component_name components robot_preset config_root root_frame parent_desc:=none emit_grasp_frame:=false"> - - + - - - - - - + params="component_api component_descriptions index components parent_component_name robot_preset config_root root_frame parent_desc:=none emit_grasp_frame:=false"> @@ -228,22 +217,19 @@ limitations under the License. - - - - + params="component_api config_root robot_preset emit_grasp_frame:=false out_name:=component_descriptions"> @@ -268,9 +252,14 @@ limitations under the License. components="${components}" robot_preset="${robot_preset}" /> + + + + - + + + + + + + + + ${values[keys[index]]} + + + + + + + + + + 0.0 + + + + + + + + + + ${joint_indices[index]} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${plugin} + + + + + + + + + diff --git a/assets/component_loader.xacro b/assets/component_loader.xacro index a73afbdc..f4536023 100644 --- a/assets/component_loader.xacro +++ b/assets/component_loader.xacro @@ -47,13 +47,12 @@ limitations under the License. - + component_cfg="${component_cfg}" component_desc="${component_desc}" component_descriptions="${dict(component=component_desc)}" out_name="component_runtime" /> diff --git a/assets/robot/openarm_v2.0/config/robot_presets/default_bimanual.yaml b/assets/robot/openarm_v2.0/config/robot_presets/default_bimanual.yaml index 2a18cc1b..559c7625 100644 --- a/assets/robot/openarm_v2.0/config/robot_presets/default_bimanual.yaml +++ b/assets/robot/openarm_v2.0/config/robot_presets/default_bimanual.yaml @@ -118,3 +118,29 @@ secondary_arm_end_effector: y: 1 z: 1 limit_override_joints: {} + +systems: + openarm_left_hardware_interface: + joints: + primary_arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} + primary_arm_end_effector: + joint1: {idx: 8} + openarm_right_hardware_interface: + joints: + secondary_arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} + secondary_arm_end_effector: + joint1: {idx: 8} diff --git a/assets/robot/openarm_v2.0/config/robot_presets/left_arm.yaml b/assets/robot/openarm_v2.0/config/robot_presets/left_arm.yaml index 66f1af6e..b4debe9d 100644 --- a/assets/robot/openarm_v2.0/config/robot_presets/left_arm.yaml +++ b/assets/robot/openarm_v2.0/config/robot_presets/left_arm.yaml @@ -122,3 +122,15 @@ secondary_arm_end_effector: y: 1 z: 1 limit_override_joints: {} + +systems: + openarm_left_hardware_interface: + joints: + primary_arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} diff --git a/assets/robot/openarm_v2.0/config/robot_presets/left_arm_with_pinch_gripper.yaml b/assets/robot/openarm_v2.0/config/robot_presets/left_arm_with_pinch_gripper.yaml index b7146b04..18fb9066 100644 --- a/assets/robot/openarm_v2.0/config/robot_presets/left_arm_with_pinch_gripper.yaml +++ b/assets/robot/openarm_v2.0/config/robot_presets/left_arm_with_pinch_gripper.yaml @@ -123,3 +123,17 @@ secondary_arm_end_effector: y: 1 z: 1 limit_override_joints: {} + +systems: + openarm_left_hardware_interface: + joints: + primary_arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} + primary_arm_end_effector: + joint1: {idx: 8} diff --git a/assets/robot/openarm_v2.0/config/robot_presets/right_arm.yaml b/assets/robot/openarm_v2.0/config/robot_presets/right_arm.yaml index fe26dd88..d62cd67c 100644 --- a/assets/robot/openarm_v2.0/config/robot_presets/right_arm.yaml +++ b/assets/robot/openarm_v2.0/config/robot_presets/right_arm.yaml @@ -122,3 +122,15 @@ secondary_arm_end_effector: y: -1 z: 1 limit_override_joints: {} + +systems: + openarm_right_hardware_interface: + joints: + primary_arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} diff --git a/assets/robot/openarm_v2.0/config/robot_presets/right_arm_with_pinch_gripper.yaml b/assets/robot/openarm_v2.0/config/robot_presets/right_arm_with_pinch_gripper.yaml index f5e60d0e..06936a6b 100644 --- a/assets/robot/openarm_v2.0/config/robot_presets/right_arm_with_pinch_gripper.yaml +++ b/assets/robot/openarm_v2.0/config/robot_presets/right_arm_with_pinch_gripper.yaml @@ -119,3 +119,17 @@ secondary_arm_end_effector: y: -1 z: 1 limit_override_joints: {} + +systems: + openarm_right_hardware_interface: + joints: + primary_arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} + primary_arm_end_effector: + joint1: {idx: 8} diff --git a/assets/robot/openarm_v2.0/urdf/example/v2.urdf b/assets/robot/openarm_v2.0/urdf/example/v2.urdf index 39ad0c70..9ae8fcba 100644 --- a/assets/robot/openarm_v2.0/urdf/example/v2.urdf +++ b/assets/robot/openarm_v2.0/urdf/example/v2.urdf @@ -711,14 +711,6 @@ limitations under the License. 0.0 - @@ -839,13 +831,5 @@ limitations under the License. 0.0 - diff --git a/assets/robot/openarm_v2.0/urdf/openarm_v20.urdf.xacro b/assets/robot/openarm_v2.0/urdf/openarm_v20.urdf.xacro index ed37d4a9..dee35f42 100644 --- a/assets/robot/openarm_v2.0/urdf/openarm_v20.urdf.xacro +++ b/assets/robot/openarm_v2.0/urdf/openarm_v20.urdf.xacro @@ -16,42 +16,42 @@ limitations under the License. - + + + - - - + + + - - - - - - - - + + + + + + + + + diff --git a/assets/robot/openarm_v2.0/urdf/ros2_control/openarm.bimanual.ros2_control.xacro b/assets/robot/openarm_v2.0/urdf/ros2_control/openarm.bimanual.ros2_control.xacro deleted file mode 100644 index e7b25ad8..00000000 --- a/assets/robot/openarm_v2.0/urdf/ros2_control/openarm.bimanual.ros2_control.xacro +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - - - - - ${arm_type} - - mock_components/GenericSystem - ${fake_sensor_commands} - 0.0 - - - openarm_hardware/OpenArmHW - ${left_can_interface} - ${left_arm_prefix} - ${can_fd} - ${ee_type} - ${control_gains['joint1']['kp']} - ${control_gains['joint2']['kp']} - ${control_gains['joint3']['kp']} - ${control_gains['joint4']['kp']} - ${control_gains['joint5']['kp']} - ${control_gains['joint6']['kp']} - ${control_gains['joint7']['kp']} - ${control_gains['joint1']['kd']} - ${control_gains['joint2']['kd']} - ${control_gains['joint3']['kd']} - ${control_gains['joint4']['kd']} - ${control_gains['joint5']['kd']} - ${control_gains['joint6']['kd']} - ${control_gains['joint7']['kd']} - - - - - - - - - - - ${initial_position} - - - - 0.0 - - - - 0.0 - - - - - - - - - - - - - - - - - - - - - ${arm_type} - - mock_components/GenericSystem - ${fake_sensor_commands} - 0.0 - - - openarm_hardware/OpenArmHW - ${right_can_interface} - ${right_arm_prefix} - ${can_fd} - ${ee_type} - ${control_gains['joint1']['kp']} - ${control_gains['joint2']['kp']} - ${control_gains['joint3']['kp']} - ${control_gains['joint4']['kp']} - ${control_gains['joint5']['kp']} - ${control_gains['joint6']['kp']} - ${control_gains['joint7']['kp']} - ${control_gains['joint1']['kd']} - ${control_gains['joint2']['kd']} - ${control_gains['joint3']['kd']} - ${control_gains['joint4']['kd']} - ${control_gains['joint5']['kd']} - ${control_gains['joint6']['kd']} - ${control_gains['joint7']['kd']} - - - - - - - - - - - - - - - - - - - - diff --git a/assets/robot/openarm_v2.0/urdf/ros2_control/openarm.ros2_control.xacro b/assets/robot/openarm_v2.0/urdf/ros2_control/openarm.ros2_control.xacro deleted file mode 100644 index 59f182b2..00000000 --- a/assets/robot/openarm_v2.0/urdf/ros2_control/openarm.ros2_control.xacro +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - ${arm_type} - ${arm_prefix} - - mock_components/GenericSystem - ${fake_sensor_commands} - 0.0 - - - openarm_hardware/OpenArmHW - ${can_interface} - ${arm_prefix} - ${hand} - ${can_fd} - ${ee_type} - ${control_gains['joint1']['kp']} - ${control_gains['joint2']['kp']} - ${control_gains['joint3']['kp']} - ${control_gains['joint4']['kp']} - ${control_gains['joint5']['kp']} - ${control_gains['joint6']['kp']} - ${control_gains['joint7']['kp']} - ${control_gains['joint1']['kd']} - ${control_gains['joint2']['kd']} - ${control_gains['joint3']['kd']} - ${control_gains['joint4']['kd']} - ${control_gains['joint5']['kd']} - ${control_gains['joint6']['kd']} - ${control_gains['joint7']['kd']} - - - - - - - - - - - - - ${initial_position} - - - - 0.0 - - - - 0.0 - - - - - - - - - - - - - - - - - - - - - - - diff --git a/launch/display_openarm.launch.py b/launch/display_openarm.launch.py index 3174b273..4471cff7 100644 --- a/launch/display_openarm.launch.py +++ b/launch/display_openarm.launch.py @@ -83,6 +83,9 @@ def robot_state_publisher_spawner( "arm_type": arm_type_str, "robot_preset": context.perform_substitution(robot_preset), "emit_grasp_frame": context.perform_substitution(emit_grasp_frame), + "ros2_control": context.perform_substitution(ros2_control), + "use_fake_hardware": context.perform_substitution(use_fake_hardware), + "fake_sensor_commands": context.perform_substitution(fake_sensor_commands), } robot_description = xacro.process_file( @@ -110,7 +113,7 @@ def generate_launch_description(): robot_preset_arg = DeclareLaunchArgument( "robot_preset", default_value="default_bimanual", - description="Robot preset for v2.0 (e.g. default_bimanual, right_arm, left_arm, right_arm_with_pinch_gripper, left_arm_with_pinch_gripper).", + description="Robot preset for v2.0 (e.g. default_bimanual, right_arm, left_arm).", ) rviz_config_arg = DeclareLaunchArgument( "rviz_config", diff --git a/test/support.py b/test/support.py index 72facef0..f40ae610 100644 --- a/test/support.py +++ b/test/support.py @@ -106,17 +106,6 @@ def package_share_at(path): def expand(files=None, version='v2.0', entry=None, **arguments): - if entry is None: - files = dict(files or {}) - files['fixture.urdf.xacro'] = ''' - - - - - -''' - entry = 'assets/fixture.urdf.xacro' entry = entry or f'assets/robot/openarm_{version}/urdf/openarm_{"v10" if version == "v1.0" else "v20"}.urdf.xacro' arguments = {k: str(v).lower() if isinstance(v, bool) else str(v) for k, v in arguments.items()} diff --git a/test/test_interfaces.py b/test/test_interfaces.py index 64d7ff1a..5d79f5d1 100644 --- a/test/test_interfaces.py +++ b/test/test_interfaces.py @@ -67,3 +67,164 @@ def test_broken_component_hook_does_not_use_fallback(interface): files['body/fixture_a/urdf/component.xacro'] = interface with pytest.raises((xacro.XacroException, ExpatError)): support.expand(files, robot_preset='fixture', ros2_control=False) + + +def control_input(): + names = ['root'] + [f'link{i}' for i in range(1, 8)] + data = support.model(names, {f'joint{i}': dict( + type='revolute', parent=names[i-1], child=names[i]) for i in range(1, 8)}) + data['control/control_gains.yaml'] = { + f'joint{i}': dict(kp=10+i, kd=i/10) for i in range(1, 8)} + spec = support.preset(arm=support.component('robot', 'fixture_control', 'openarm_right_'), + tool=support.component('end_effector', 'pinch_gripper', 'openarm_right_', connection=dict(attach_to='arm'))) + spec['systems'] = {'fixture_system': dict( + hardware_plugin='openarm_hardware/OpenArmHW', can_interface='can_test', can_fd=True, + joints=dict(arm={name: dict(idx=i) for i, name in enumerate(data['struct/topology.yaml']['joints'])}, + tool=dict(joint1=dict(idx=8))))} + return spec, {'arm': data, 'tool': support.pinch()} + + +def test_control_joints_follow_model_names_and_enabled_components(): + spec, data = control_input() + spec['arm']['prefix'], spec['tool']['prefix'] = 'drive_', 'tool_' + arm_joints = data['arm']['struct/topology.yaml']['joints'] + arm_joints['joint7']['name'] = 'wrist' + selection = spec['systems']['fixture_system']['joints']['arm'] + spec['systems']['fixture_system']['joints']['arm'] = dict( + reversed(list(selection.items()))) + assert not support.assemble( + spec, data, ros2_control=False).findall('ros2_control') + for tool_enabled in (False, True): + spec['tool']['enabled'] = tool_enabled + robot = support.assemble( + spec, data, ros2_control=True, use_fake_hardware=True) + expected = {spec['arm']['prefix'] + cfg.get('name', name) + for name, cfg in arm_joints.items()} + if tool_enabled: + expected.update(spec['tool']['prefix'] + cfg.get('name', name) + for name, cfg in data['tool']['struct/topology.yaml']['joints'].items() + if name not in data['tool']['joint/joint_mimics.yaml']) + active = {joint.get('name') for joint in robot.findall('joint') + if joint.get('type') != 'fixed' and joint.find('mimic') is None} + assert active == expected + assert {joint.get('name') + for joint in robot.findall('ros2_control/joint')} == active + expected_indices = {spec[component]['prefix'] + data[component]['struct/topology.yaml']['joints'][name].get('name', name): cfg['idx'] + for component, joints in spec['systems']['fixture_system']['joints'].items() + if spec[component]['enabled'] for name, cfg in joints.items()} + actual_indices = {joint.get('name'): int(joint.find("param[@name='idx']").text) + for joint in robot.findall('ros2_control/joint')} + assert actual_indices == expected_indices + assert list(actual_indices.values()) == sorted( + expected_indices.values()) + + data['arm']['struct/topology.yaml']['collapse_empty_end'] = True + spec['tool']['connection']['parent_reference_point'] = 'port' + spec['systems']['fixture_system']['joints']['tool']['joint2'] = dict( + idx=9) + files = support.files_for(spec, data) + files['end_effector/pinch_gripper/urdf/component.xacro'] = ''' + + + + + ''' + robot = support.expand(files, robot_preset='fixture', + ros2_control=True, use_fake_hardware=True) + assert robot.find("joint[@name='tool_finger_joint2']/mimic") is None + expected.add('tool_finger_joint2') + active = {joint.get('name') for joint in robot.findall('joint') + if joint.get('type') != 'fixed' and joint.find('mimic') is None} + assert active == expected + assert {joint.get('name') + for joint in robot.findall('ros2_control/joint')} == active + + spec, data = control_input() + joints = list(data['arm']['struct/topology.yaml']['joints']) + spec['systems'] = { + 'shoulder': dict(joints=dict(arm={name: dict(idx=2*i-1) for i, name in enumerate(joints[:4], 1)})), + 'wrist': dict(joints=dict(arm={name: dict(idx=2*i-1) for i, name in enumerate(joints[4:], 1)}, + tool=dict(joint1=dict(idx=7))))} + robot = support.assemble( + spec, data, ros2_control=True, use_fake_hardware=True) + for name, cfg in spec['systems'].items(): + expected = {spec[component]['prefix'] + data[component]['struct/topology.yaml']['joints'][joint].get('name', joint) for component, + names in cfg['joints'].items() for joint in names} + assert {joint.get('name') for joint in robot.find( + f"ros2_control[@name='{name}']").findall('joint')} == expected + spec['systems']['shoulder'].update( + hardware_plugin='openarm_hardware/OpenArmHW', can_interface='can_test') + with pytest.raises(xacro.XacroException, match='seven arm joints'): + support.assemble(spec, data, ros2_control=True, + use_fake_hardware=False) + spec['systems']['wrist']['joints']['arm'][joints[0]] = dict(idx=9) + with pytest.raises(xacro.XacroException, match='duplicate joint assignment'): + support.assemble(spec, data, ros2_control=True, use_fake_hardware=True) + spec['systems']['wrist']['joints']['arm']['missing'] = spec['systems']['wrist']['joints']['arm'].pop( + joints[0]) + with pytest.raises(xacro.XacroException, match='unknown joint'): + support.assemble(spec, data, ros2_control=True, use_fake_hardware=True) + del spec['systems']['wrist']['joints']['arm']['missing'] + for invalid_idx in (-1, True, 1.5): + spec['systems']['wrist']['joints']['tool']['joint1']['idx'] = invalid_idx + with pytest.raises(xacro.XacroException, match='non-negative integer idx'): + support.assemble(spec, data, ros2_control=True, + use_fake_hardware=True) + spec['systems']['wrist']['joints']['tool']['joint1']['idx'] = 1 + with pytest.raises(xacro.XacroException, match='duplicate idx'): + support.assemble(spec, data, ros2_control=True, use_fake_hardware=True) + + +def test_hardware_parameters_follow_input(): + spec, data = control_input() + control = spec['systems']['fixture_system'] + for prefix, can_interface in [('openarm_left_', 'can_left_test'), + ('openarm_right_', 'can_right_test')]: + control.update(can_interface=can_interface, can_fd=False) + for name in ('arm', 'tool'): + spec[name]['prefix'] = prefix + robot = support.assemble(spec, data, ros2_control=True, + use_fake_hardware=False) + hardware = robot.find('ros2_control/hardware') + assert hardware.find('plugin').text == control['hardware_plugin'] + params = {p.get('name'): p.text for p in hardware.findall('param')} + assert len(params) == len(hardware.findall('param')) + assert params['can_interface'] == control['can_interface'] + assert params['can_fd'].lower() == 'false' + assert params['arm_prefix'] == prefix.removeprefix('openarm_') + assert params['ee_type'] == spec['tool']['product'] + for name, gains in data['arm']['control/control_gains.yaml'].items(): + for key, value in gains.items(): + assert float(params[key+name.removeprefix('joint')]) == value + + for side in ('left', 'right'): + spec['systems'] = {f'openarm_{side}_hardware_interface': control} + control.update(can_fd=True) + overrides = dict(left_can_interface='runtime_left', + right_can_interface='runtime_right', can_fd=False) + robot = support.assemble(spec, data, ros2_control=True, + use_fake_hardware=False, **overrides) + hardware = robot.find('ros2_control/hardware') + params = {p.get('name'): p.text for p in hardware.findall('param')} + assert params['can_interface'] == overrides[side + '_can_interface'] + assert params['can_fd'].lower() == 'false' + + robot = support.assemble(spec, data, ros2_control=True, + use_fake_hardware=True, fake_sensor_commands=True) + hardware = robot.find('ros2_control/hardware') + assert hardware.find('plugin').text == 'mock_components/GenericSystem' + params = {p.get('name'): p.text for p in hardware.findall('param')} + assert params['mock_sensor_commands'].lower() == 'true' + assert float(params['position_state_following_offset']) == 0.0 + assert 'fake_sensor_commands' not in params and 'state_following_offset' not in params + + control.update(command_interfaces=[ + 'position'], state_interfaces=['position']) + robot = support.assemble( + spec, data, ros2_control=True, use_fake_hardware=True) + for joint in robot.findall('ros2_control/joint'): + assert [i.get('name') for i in joint.findall( + 'command_interface')] == ['position'] + assert [i.get('name') + for i in joint.findall('state_interface')] == ['position'] diff --git a/test/test_models.py b/test/test_models.py new file mode 100644 index 00000000..57716a88 --- /dev/null +++ b/test/test_models.py @@ -0,0 +1,43 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from pathlib import Path +from urllib.parse import urlparse + +from support import ROOT, expand, packages + + +def test_shipped_presets_expand_and_resolve_resources(): + robots = [] + for version in ('v2.0',): + folder = ROOT/f'assets/robot/openarm_{version}/config/robot_presets' + robots.append((version, '', expand(version=version, ros2_control=True, + use_fake_hardware=True, emit_grasp_frame=True))) + for path in sorted(folder.glob('*.yaml')): + robot = expand(version=version, robot_preset=path.stem, ros2_control=True, + use_fake_hardware=True, emit_grasp_frame=True) + robots.append((version, path.stem, robot)) + for path in sorted((ROOT/'assets/end_effector').glob('pinch_gripper/urdf/*_standalone.urdf.xacro')): + robots.append(('standalone', path.name, expand( + entry=str(path.relative_to(ROOT))))) + for version, name, robot in robots: + for mesh in robot.findall('.//geometry/mesh'): + uri = urlparse(mesh.get('filename')) + if uri.scheme == 'package': + share = ROOT if uri.netloc == 'openarm_description' else Path( + packages.get_package_share_directory(uri.netloc)) + assert (share/uri.path.lstrip('/') + ).is_file(), (version, name, mesh.attrib) + elif uri.scheme in ('', 'file'): + assert Path(uri.path).is_file(), (version, name, mesh.attrib) From f0a9f023226de246893bc8f3ca0edef4ab047c68 Mon Sep 17 00:00:00 2001 From: li-strix <128799116+stevenaya@users.noreply.github.com> Date: Fri, 6 Nov 2026 19:24:41 +0900 Subject: [PATCH 3/3] Migrate V1 assembly to shared presets and stable component keys --- .../v1.0/config/inertials/nominal.yaml} | 12 +- assets/body/v1.0/config/link/collisions.yaml | 28 ++ assets/body/v1.0/config/link/visuals.yaml | 28 ++ .../v1.0/config/struct/reference_points.yaml | 34 ++ .../v1.0/config/struct/topology.yaml} | 14 +- .../meshes}/collision/body_link0_symp.stl | Bin .../v1.0/meshes}/visual/body_link0.dae | 0 .../v1.0/meshes}/visual/body_link0.stl | Bin .../nominal.yaml} | 28 +- .../config/joint/joint_axes.yaml} | 20 +- .../config/{ => joint}/joint_limits.yaml | 8 +- .../config/joint/joint_mimics.yaml | 18 + .../joint_origins.yaml} | 23 +- .../parallel_link/config/link/collisions.yaml | 70 ++++ .../parallel_link/config/link/visuals.yaml | 70 ++++ .../config/struct/reference_points.yaml | 24 ++ .../parallel_link/config/struct/topology.yaml | 39 ++ .../parallel_link/meshes/collision/link7.stl} | Bin .../parallel_link/meshes}/visual/link7.dae | 0 .../parallel_link/meshes}/visual/link7.stl | Bin .../urdf/parallel_link_standalone.urdf.xacro | 40 +- .../arm/{ => control}/control_gains.yaml | 7 - .../nominal.yaml} | 53 +-- .../config/arm/joint/joint_axes.yaml} | 61 +-- .../config/arm/{ => joint}/joint_limits.yaml | 22 +- .../joint_origins.yaml} | 51 +-- .../config/arm/kinematics_link.yaml | 94 ----- .../config/arm/kinematics_offset.yaml | 85 ---- .../config/arm/link/collisions.yaml | 112 +++++ .../openarm_v1.0/config/arm/link/visuals.yaml | 112 +++++ .../config/arm/struct/name_mapping.yaml | 33 ++ .../config/arm/struct/reference_points.yaml | 24 ++ .../config/arm/struct/topology.yaml | 61 +++ .../robot_presets/default_bimanual.yaml | 174 ++++++++ .../config/robot_presets/default_single.yaml | 72 ++++ .../config/robot_presets/left_arm.yaml | 66 +++ .../left_arm_with_parallel_link.yaml | 88 ++++ .../config/robot_presets/right_arm.yaml | 50 +++ .../right_arm_with_parallel_link.yaml | 72 ++++ .../openarm_v1.0/urdf/arm/openarm_arm.xacro | 123 ------ .../openarm_v1.0/urdf/arm/openarm_macro.xacro | 150 ------- .../openarm_v1.0/urdf/body/openarm_body.xacro | 49 --- .../urdf/body/openarm_body_macro.xacro | 68 ---- .../openarm_v1.0/urdf/ee/ee_dispatcher.xacro | 37 -- .../urdf/ee/openarm_ee_macro.xacro | 94 ----- .../openarm_parallel_gripper.xacro | 106 ----- .../openarm_v20_pinch_gripper.xacro | 102 ----- .../robot/openarm_v1.0/urdf/example/v1.urdf | 384 +++++++++--------- .../openarm_v1.0/urdf/openarm_v10.urdf.xacro | 101 ++--- .../urdf/robot/openarm_robot.xacro | 202 --------- .../openarm.bimanual.ros2_control.xacro | 152 ------- .../ros2_control/openarm.ros2_control.xacro | 110 ----- launch/display_openarm.launch.py | 7 +- test/test_entrypoints.py | 16 +- test/test_models.py | 4 +- 55 files changed, 1571 insertions(+), 1827 deletions(-) rename assets/{robot/openarm_v1.0/config/body/inertials.yaml => body/v1.0/config/inertials/nominal.yaml} (83%) create mode 100644 assets/body/v1.0/config/link/collisions.yaml create mode 100644 assets/body/v1.0/config/link/visuals.yaml create mode 100644 assets/body/v1.0/config/struct/reference_points.yaml rename assets/{robot/openarm_v1.0/config/body/kinematics_link.yaml => body/v1.0/config/struct/topology.yaml} (80%) rename assets/{robot/openarm_v1.0/mesh/body => body/v1.0/meshes}/collision/body_link0_symp.stl (100%) rename assets/{robot/openarm_v1.0/mesh/body => body/v1.0/meshes}/visual/body_link0.dae (100%) rename assets/{robot/openarm_v1.0/mesh/body => body/v1.0/meshes}/visual/body_link0.stl (100%) rename assets/end_effector/parallel_link/config/{inertials.yaml => inertials/nominal.yaml} (80%) rename assets/{robot/openarm_v1.0/config/body/kinematics.yaml => end_effector/parallel_link/config/joint/joint_axes.yaml} (80%) rename assets/end_effector/parallel_link/config/{ => joint}/joint_limits.yaml (87%) create mode 100644 assets/end_effector/parallel_link/config/joint/joint_mimics.yaml rename assets/end_effector/parallel_link/config/{kinematics.yaml => joint/joint_origins.yaml} (81%) create mode 100644 assets/end_effector/parallel_link/config/link/collisions.yaml create mode 100644 assets/end_effector/parallel_link/config/link/visuals.yaml create mode 100644 assets/end_effector/parallel_link/config/struct/reference_points.yaml create mode 100644 assets/end_effector/parallel_link/config/struct/topology.yaml rename assets/{robot/openarm_v1.0/mesh/arm/collision/link7_symp.stl => end_effector/parallel_link/meshes/collision/link7.stl} (100%) rename assets/{robot/openarm_v1.0/mesh/arm => end_effector/parallel_link/meshes}/visual/link7.dae (100%) rename assets/{robot/openarm_v1.0/mesh/arm => end_effector/parallel_link/meshes}/visual/link7.stl (100%) rename assets/robot/openarm_v1.0/config/arm/{ => control}/control_gains.yaml (99%) rename assets/robot/openarm_v1.0/config/arm/{inertials.yaml => inertials/nominal.yaml} (84%) rename assets/{end_effector/parallel_link/config/kinematics_link.yaml => robot/openarm_v1.0/config/arm/joint/joint_axes.yaml} (63%) rename assets/robot/openarm_v1.0/config/arm/{ => joint}/joint_limits.yaml (83%) rename assets/robot/openarm_v1.0/config/arm/{kinematics.yaml => joint/joint_origins.yaml} (70%) delete mode 100644 assets/robot/openarm_v1.0/config/arm/kinematics_link.yaml delete mode 100644 assets/robot/openarm_v1.0/config/arm/kinematics_offset.yaml create mode 100644 assets/robot/openarm_v1.0/config/arm/link/collisions.yaml create mode 100644 assets/robot/openarm_v1.0/config/arm/link/visuals.yaml create mode 100644 assets/robot/openarm_v1.0/config/arm/struct/name_mapping.yaml create mode 100644 assets/robot/openarm_v1.0/config/arm/struct/reference_points.yaml create mode 100644 assets/robot/openarm_v1.0/config/arm/struct/topology.yaml create mode 100644 assets/robot/openarm_v1.0/config/robot_presets/default_bimanual.yaml create mode 100644 assets/robot/openarm_v1.0/config/robot_presets/default_single.yaml create mode 100644 assets/robot/openarm_v1.0/config/robot_presets/left_arm.yaml create mode 100644 assets/robot/openarm_v1.0/config/robot_presets/left_arm_with_parallel_link.yaml create mode 100644 assets/robot/openarm_v1.0/config/robot_presets/right_arm.yaml create mode 100644 assets/robot/openarm_v1.0/config/robot_presets/right_arm_with_parallel_link.yaml delete mode 100644 assets/robot/openarm_v1.0/urdf/arm/openarm_arm.xacro delete mode 100644 assets/robot/openarm_v1.0/urdf/arm/openarm_macro.xacro delete mode 100644 assets/robot/openarm_v1.0/urdf/body/openarm_body.xacro delete mode 100644 assets/robot/openarm_v1.0/urdf/body/openarm_body_macro.xacro delete mode 100644 assets/robot/openarm_v1.0/urdf/ee/ee_dispatcher.xacro delete mode 100644 assets/robot/openarm_v1.0/urdf/ee/openarm_ee_macro.xacro delete mode 100644 assets/robot/openarm_v1.0/urdf/ee/parallel_link/openarm_parallel_gripper.xacro delete mode 100644 assets/robot/openarm_v1.0/urdf/ee/pinch_gripper/openarm_v20_pinch_gripper.xacro delete mode 100644 assets/robot/openarm_v1.0/urdf/robot/openarm_robot.xacro delete mode 100644 assets/robot/openarm_v1.0/urdf/ros2_control/openarm.bimanual.ros2_control.xacro delete mode 100644 assets/robot/openarm_v1.0/urdf/ros2_control/openarm.ros2_control.xacro diff --git a/assets/robot/openarm_v1.0/config/body/inertials.yaml b/assets/body/v1.0/config/inertials/nominal.yaml similarity index 83% rename from assets/robot/openarm_v1.0/config/body/inertials.yaml rename to assets/body/v1.0/config/inertials/nominal.yaml index a9207078..a5f056fd 100644 --- a/assets/robot/openarm_v1.0/config/body/inertials.yaml +++ b/assets/body/v1.0/config/inertials/nominal.yaml @@ -1,4 +1,4 @@ -# Copyright 2025 Enactic, Inc. +# Copyright 2026 Enactic, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,10 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -body_link0: +link1: origin: - xyz: -0.016206894902 0 0.244091987626 - rpy: 0.0 0.0 0.0 + x: -0.016206894902 + y: 0.0 + z: 0.244091987626 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 mass: 3.74 inertia: xx: 0.248946829107 diff --git a/assets/body/v1.0/config/link/collisions.yaml b/assets/body/v1.0/config/link/collisions.yaml new file mode 100644 index 00000000..b3c0b2d0 --- /dev/null +++ b/assets/body/v1.0/config/link/collisions.yaml @@ -0,0 +1,28 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +link1: + origin: + x: 0 + y: 0 + z: 0 + roll: 0 + pitch: 0 + yaw: 0 + geometry: + mesh: package://openarm_description/assets/body/v1.0/meshes/collision/body_link0_symp.stl + scale: + x: 0.001 + y: 0.001 + z: 0.001 diff --git a/assets/body/v1.0/config/link/visuals.yaml b/assets/body/v1.0/config/link/visuals.yaml new file mode 100644 index 00000000..5a34ffe4 --- /dev/null +++ b/assets/body/v1.0/config/link/visuals.yaml @@ -0,0 +1,28 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +link1: + origin: + x: 0 + y: 0 + z: 0 + roll: 0 + pitch: 0 + yaw: 0 + geometry: + mesh: package://openarm_description/assets/body/v1.0/meshes/visual/body_link0.dae + scale: + x: 0.001 + y: 0.001 + z: 0.001 diff --git a/assets/body/v1.0/config/struct/reference_points.yaml b/assets/body/v1.0/config/struct/reference_points.yaml new file mode 100644 index 00000000..c450202f --- /dev/null +++ b/assets/body/v1.0/config/struct/reference_points.yaml @@ -0,0 +1,34 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +left_arm_mount_point: + parent: link1 + emit: false + origin: + x: 0 + y: 0.03 + z: 0.697 + roll: -1.5708 + pitch: 0 + yaw: 0 +right_arm_mount_point: + parent: link1 + emit: false + origin: + x: 0 + y: -0.03 + z: 0.697 + roll: 1.5708 + pitch: 0 + yaw: 0 diff --git a/assets/robot/openarm_v1.0/config/body/kinematics_link.yaml b/assets/body/v1.0/config/struct/topology.yaml similarity index 80% rename from assets/robot/openarm_v1.0/config/body/kinematics_link.yaml rename to assets/body/v1.0/config/struct/topology.yaml index bbe02232..97b46d61 100644 --- a/assets/robot/openarm_v1.0/config/body/kinematics_link.yaml +++ b/assets/body/v1.0/config/struct/topology.yaml @@ -1,4 +1,4 @@ -# Copyright 2025 Enactic, Inc. +# Copyright 2026 Enactic, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,11 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -body_link0: - kinematic: - x: 0.0 - y: 0.0 - z: 0.0 - roll: 0.0 - pitch: 0.0 - yaw: 0.0 +links: + link1: + name: body_link0 +joints: {} diff --git a/assets/robot/openarm_v1.0/mesh/body/collision/body_link0_symp.stl b/assets/body/v1.0/meshes/collision/body_link0_symp.stl similarity index 100% rename from assets/robot/openarm_v1.0/mesh/body/collision/body_link0_symp.stl rename to assets/body/v1.0/meshes/collision/body_link0_symp.stl diff --git a/assets/robot/openarm_v1.0/mesh/body/visual/body_link0.dae b/assets/body/v1.0/meshes/visual/body_link0.dae similarity index 100% rename from assets/robot/openarm_v1.0/mesh/body/visual/body_link0.dae rename to assets/body/v1.0/meshes/visual/body_link0.dae diff --git a/assets/robot/openarm_v1.0/mesh/body/visual/body_link0.stl b/assets/body/v1.0/meshes/visual/body_link0.stl similarity index 100% rename from assets/robot/openarm_v1.0/mesh/body/visual/body_link0.stl rename to assets/body/v1.0/meshes/visual/body_link0.stl diff --git a/assets/end_effector/parallel_link/config/inertials.yaml b/assets/end_effector/parallel_link/config/inertials/nominal.yaml similarity index 80% rename from assets/end_effector/parallel_link/config/inertials.yaml rename to assets/end_effector/parallel_link/config/inertials/nominal.yaml index 49a29294..ef52c40b 100644 --- a/assets/end_effector/parallel_link/config/inertials.yaml +++ b/assets/end_effector/parallel_link/config/inertials/nominal.yaml @@ -12,7 +12,23 @@ # See the License for the specific language governing permissions and # limitations under the License. -hand: +link1: + origin: + x: -9.897454675528511e-05 + y: 0.003372444724450437 + z: 0.06138919729233123 + roll: 0 + pitch: 0 + yaw: 0 + mass: 0.4054971268153967 + inertia: + xx: 0.0003637830920674498 + yy: 0.0003351190950225729 + zz: 0.0001865112723189818 + xy: 0.0 + xz: 0.0 + yz: 7.094884219324384e-05 +link2: origin: x: 0 y: 0 @@ -26,10 +42,9 @@ hand: yy: 5.560627616753029e-05 zz: 0.0002906093338421478 xy: 1.18380219510342e-05 - xz: 0 - yz: 0 - -left_finger: + xz: 0.0 + yz: 0.0 +link4: origin: x: -0.004646697332048465 y: 0.01217890651468325 @@ -45,8 +60,7 @@ left_finger: xy: -4.813534779503441e-07 xz: -4.110240982958172e-06 yz: 3.504307786795564e-06 - -right_finger: +link3: origin: x: 0.004646697332048465 y: -0.01217890651468325 diff --git a/assets/robot/openarm_v1.0/config/body/kinematics.yaml b/assets/end_effector/parallel_link/config/joint/joint_axes.yaml similarity index 80% rename from assets/robot/openarm_v1.0/config/body/kinematics.yaml rename to assets/end_effector/parallel_link/config/joint/joint_axes.yaml index bbe02232..2e58649d 100644 --- a/assets/robot/openarm_v1.0/config/body/kinematics.yaml +++ b/assets/end_effector/parallel_link/config/joint/joint_axes.yaml @@ -1,4 +1,4 @@ -# Copyright 2025 Enactic, Inc. +# Copyright 2026 Enactic, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,11 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -body_link0: - kinematic: - x: 0.0 - y: 0.0 - z: 0.0 - roll: 0.0 - pitch: 0.0 - yaw: 0.0 +joint2: + axis: + x: 0 + y: -1 + z: 0 +joint3: + axis: + x: 0 + y: 1 + z: 0 diff --git a/assets/end_effector/parallel_link/config/joint_limits.yaml b/assets/end_effector/parallel_link/config/joint/joint_limits.yaml similarity index 87% rename from assets/end_effector/parallel_link/config/joint_limits.yaml rename to assets/end_effector/parallel_link/config/joint/joint_limits.yaml index ee715e39..9f2ba38b 100644 --- a/assets/end_effector/parallel_link/config/joint_limits.yaml +++ b/assets/end_effector/parallel_link/config/joint/joint_limits.yaml @@ -12,7 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -finger_joint: +joint2: + limit: + lower: 0.0 + upper: 0.044 + velocity: 0.661 + effort: 150.75 +joint3: limit: lower: 0.0 upper: 0.044 diff --git a/assets/end_effector/parallel_link/config/joint/joint_mimics.yaml b/assets/end_effector/parallel_link/config/joint/joint_mimics.yaml new file mode 100644 index 00000000..0994fd21 --- /dev/null +++ b/assets/end_effector/parallel_link/config/joint/joint_mimics.yaml @@ -0,0 +1,18 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +joint3: + joint: joint2 + multiplier: 1 + offset: 0 diff --git a/assets/end_effector/parallel_link/config/kinematics.yaml b/assets/end_effector/parallel_link/config/joint/joint_origins.yaml similarity index 81% rename from assets/end_effector/parallel_link/config/kinematics.yaml rename to assets/end_effector/parallel_link/config/joint/joint_origins.yaml index 0723f094..09b9da8f 100644 --- a/assets/end_effector/parallel_link/config/kinematics.yaml +++ b/assets/end_effector/parallel_link/config/joint/joint_origins.yaml @@ -12,20 +12,27 @@ # See the License for the specific language governing permissions and # limitations under the License. -hand: - kinematic: - x: 0.0 - y: 0.0 +joint1: + origin: + x: 0 + y: 0 z: 0.1001 roll: 0 pitch: 0 yaw: 0 - -finger_joint: - kinematic: - x: 0.0 +joint2: + origin: + x: 0 y: -0.005 z: 0.015 roll: 0 pitch: 0 yaw: 0 +joint3: + origin: + x: 0 + y: 0.005 + z: 0.015 + roll: 0 + pitch: 0 + yaw: 0 diff --git a/assets/end_effector/parallel_link/config/link/collisions.yaml b/assets/end_effector/parallel_link/config/link/collisions.yaml new file mode 100644 index 00000000..ff1821eb --- /dev/null +++ b/assets/end_effector/parallel_link/config/link/collisions.yaml @@ -0,0 +1,70 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +link1: + origin: + x: 0.0 + y: -0.0 + z: -0.5585 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/end_effector/parallel_link/meshes/collision/link7.stl + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link2: + origin: + x: 0.0 + y: 0.0 + z: -0.6586 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/end_effector/parallel_link/meshes/collision/hand.stl + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link4: + origin: + x: 0.0 + y: -0.05 + z: -0.673001 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/end_effector/parallel_link/meshes/collision/finger.stl + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link3: + origin: + x: 0.0 + y: 0.05 + z: -0.673001 + roll: 0.0 + pitch: 0.0 + yaw: 3.141592653589793 + geometry: + mesh: package://openarm_description/assets/end_effector/parallel_link/meshes/collision/finger.stl + scale: + x: 0.001 + y: 0.001 + z: 0.001 diff --git a/assets/end_effector/parallel_link/config/link/visuals.yaml b/assets/end_effector/parallel_link/config/link/visuals.yaml new file mode 100644 index 00000000..adfeb92e --- /dev/null +++ b/assets/end_effector/parallel_link/config/link/visuals.yaml @@ -0,0 +1,70 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +link1: + origin: + x: 0.0 + y: -0.0 + z: -0.5585 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/end_effector/parallel_link/meshes/visual/link7.dae + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link2: + origin: + x: 0.0 + y: 0.0 + z: -0.6586 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/end_effector/parallel_link/meshes/visual/hand.dae + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link4: + origin: + x: 0.0 + y: -0.05 + z: -0.673001 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/end_effector/parallel_link/meshes/visual/finger.dae + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link3: + origin: + x: 0.0 + y: 0.05 + z: -0.673001 + roll: 0.0 + pitch: 0.0 + yaw: 3.141592653589793 + geometry: + mesh: package://openarm_description/assets/end_effector/parallel_link/meshes/visual/finger.dae + scale: + x: 0.001 + y: 0.001 + z: 0.001 diff --git a/assets/end_effector/parallel_link/config/struct/reference_points.yaml b/assets/end_effector/parallel_link/config/struct/reference_points.yaml new file mode 100644 index 00000000..39a77980 --- /dev/null +++ b/assets/end_effector/parallel_link/config/struct/reference_points.yaml @@ -0,0 +1,24 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +hand_tcp: + parent: link2 + emit: true + origin: + x: 0 + y: 0 + z: 0.09 + roll: 0 + pitch: 0 + yaw: 0 diff --git a/assets/end_effector/parallel_link/config/struct/topology.yaml b/assets/end_effector/parallel_link/config/struct/topology.yaml new file mode 100644 index 00000000..c06793d5 --- /dev/null +++ b/assets/end_effector/parallel_link/config/struct/topology.yaml @@ -0,0 +1,39 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +links: + link1: + name: link7 + link2: + name: hand + link3: + name: right_finger + link4: + name: left_finger +joints: + joint1: + name: hand_joint + type: fixed + parent: link1 + child: link2 + joint2: + name: finger_joint1 + type: prismatic + parent: link2 + child: link3 + joint3: + name: finger_joint2 + type: prismatic + parent: link2 + child: link4 diff --git a/assets/robot/openarm_v1.0/mesh/arm/collision/link7_symp.stl b/assets/end_effector/parallel_link/meshes/collision/link7.stl similarity index 100% rename from assets/robot/openarm_v1.0/mesh/arm/collision/link7_symp.stl rename to assets/end_effector/parallel_link/meshes/collision/link7.stl diff --git a/assets/robot/openarm_v1.0/mesh/arm/visual/link7.dae b/assets/end_effector/parallel_link/meshes/visual/link7.dae similarity index 100% rename from assets/robot/openarm_v1.0/mesh/arm/visual/link7.dae rename to assets/end_effector/parallel_link/meshes/visual/link7.dae diff --git a/assets/robot/openarm_v1.0/mesh/arm/visual/link7.stl b/assets/end_effector/parallel_link/meshes/visual/link7.stl similarity index 100% rename from assets/robot/openarm_v1.0/mesh/arm/visual/link7.stl rename to assets/end_effector/parallel_link/meshes/visual/link7.stl diff --git a/assets/end_effector/parallel_link/urdf/parallel_link_standalone.urdf.xacro b/assets/end_effector/parallel_link/urdf/parallel_link_standalone.urdf.xacro index 21416084..21975c29 100644 --- a/assets/end_effector/parallel_link/urdf/parallel_link_standalone.urdf.xacro +++ b/assets/end_effector/parallel_link/urdf/parallel_link_standalone.urdf.xacro @@ -13,27 +13,27 @@ limitations under the License. --> - - - - + - + + - - - - + + + + + + + + + + + + + + + diff --git a/assets/robot/openarm_v1.0/config/arm/control_gains.yaml b/assets/robot/openarm_v1.0/config/arm/control/control_gains.yaml similarity index 99% rename from assets/robot/openarm_v1.0/config/arm/control_gains.yaml rename to assets/robot/openarm_v1.0/config/arm/control/control_gains.yaml index 54452fd7..a89644b9 100644 --- a/assets/robot/openarm_v1.0/config/arm/control_gains.yaml +++ b/assets/robot/openarm_v1.0/config/arm/control/control_gains.yaml @@ -15,31 +15,24 @@ joint1: kp: 70.0 kd: 2.75 - joint2: kp: 70.0 kd: 2.5 - joint3: kp: 70.0 kd: 2.0 - joint4: kp: 60.0 kd: 2.0 - joint5: kp: 10.0 kd: 0.7 - joint6: kp: 10.0 kd: 0.6 - joint7: kp: 10.0 kd: 0.5 - hand: kp: 5.0 kd: 0.1 diff --git a/assets/robot/openarm_v1.0/config/arm/inertials.yaml b/assets/robot/openarm_v1.0/config/arm/inertials/nominal.yaml similarity index 84% rename from assets/robot/openarm_v1.0/config/arm/inertials.yaml rename to assets/robot/openarm_v1.0/config/arm/inertials/nominal.yaml index b743b66a..e55e924d 100644 --- a/assets/robot/openarm_v1.0/config/arm/inertials.yaml +++ b/assets/robot/openarm_v1.0/config/arm/inertials/nominal.yaml @@ -1,4 +1,4 @@ -# Copyright 2025 Enactic, Inc. +# Copyright 2026 Enactic, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -link0: +link1: origin: x: -0.0009483362816297526 y: 0.0001580207020448382 @@ -28,8 +28,7 @@ link0: yy: 0.000962 yz: -7.0e-06 zz: 0.00147 - -link1: +link2: origin: x: 0.0011467657911800769 y: 3.319987657026362e-05 @@ -43,10 +42,9 @@ link1: xy: -1.0e-06 xz: -2.9e-05 yy: 0.001273 - yz: 1e-06 + yz: 1.0e-06 zz: 0.001016 - -link2: +link3: origin: x: 0.00839629182351943 y: -2.0145102027597523e-08 @@ -57,13 +55,12 @@ link2: mass: 0.2775092746011571 inertia: xx: 0.000359 - xy: 1e-06 + xy: 1.0e-06 xz: -0.000109 yy: 0.000376 - yz: 1e-06 + yz: 1.0e-06 zz: 0.000232 - -link3: +link4: origin: x: -0.002104752099628911 y: 0.0005549085042607548 @@ -74,13 +71,12 @@ link3: mass: 1.073863338202347 inertia: xx: 0.004372 - xy: 1e-06 + xy: 1.0e-06 xz: 1.1e-05 yy: 0.004319 yz: -3.6e-05 zz: 0.000661 - -link4: +link5: origin: x: -0.0029006831074562967 y: -0.03030575826634669 @@ -96,8 +92,7 @@ link4: yy: 0.000511 yz: 3.8e-05 zz: 0.000334 - -link5: +link6: origin: x: -0.003049665024221911 y: 0.0008866902457326625 @@ -113,8 +108,7 @@ link5: yy: 0.000445 yz: -6.0e-06 zz: 0.000324 - -link6: +link7: origin: x: -0.037136587005447405 y: 0.00033230528343419053 @@ -125,25 +119,8 @@ link6: mass: 0.475202773187987 inertia: xx: 0.000143 - xy: 1e-06 - xz: 1e-06 + xy: 1.0e-06 + xz: 1.0e-06 yy: 0.000157 - yz: 1e-06 + yz: 1.0e-06 zz: 0.000159 - -link7: - origin: - x: -9.897454675528511e-05 - y: 0.003372444724450437 - z: 0.06138919729233123 - roll: 0 - pitch: 0 - yaw: 0 - mass: 0.4054971268153967 - inertia: - xx: 0.0003637830920674498 - yy: 0.0003351190950225729 - zz: 0.0001865112723189818 - xy: 0 - xz: 0 - yz: 7.094884219324384e-05 diff --git a/assets/end_effector/parallel_link/config/kinematics_link.yaml b/assets/robot/openarm_v1.0/config/arm/joint/joint_axes.yaml similarity index 63% rename from assets/end_effector/parallel_link/config/kinematics_link.yaml rename to assets/robot/openarm_v1.0/config/arm/joint/joint_axes.yaml index d6cee252..8eb1b089 100644 --- a/assets/end_effector/parallel_link/config/kinematics_link.yaml +++ b/assets/robot/openarm_v1.0/config/arm/joint/joint_axes.yaml @@ -12,29 +12,38 @@ # See the License for the specific language governing permissions and # limitations under the License. -hand: - kinematic: - x: 0.0 - y: 0.0 - z: -0.6586 - roll: 0.0 - pitch: 0.0 - yaw: 0.0 - -left_finger: - kinematic: - x: 0.0 - y: -0.05 - z: -0.673001 - roll: 0.0 - pitch: 0.0 - yaw: 0.0 - -right_finger: - kinematic: - x: 0.0 - y: 0.05 - z: -0.673001 - roll: 0.0 - pitch: 0.0 - yaw: 3.141592653589793 +joint1: + axis: + x: 0 + y: 0 + z: 1 +joint2: + axis: + x: -1 + y: 0 + z: 0 +joint3: + axis: + x: 0 + y: 0 + z: 1 +joint4: + axis: + x: 0 + y: 1 + z: 0 +joint5: + axis: + x: 0 + y: 0 + z: 1 +joint6: + axis: + x: 1 + y: 0 + z: 0 +joint7: + axis: + x: 0 + y: 1 + z: 0 diff --git a/assets/robot/openarm_v1.0/config/arm/joint_limits.yaml b/assets/robot/openarm_v1.0/config/arm/joint/joint_limits.yaml similarity index 83% rename from assets/robot/openarm_v1.0/config/arm/joint_limits.yaml rename to assets/robot/openarm_v1.0/config/arm/joint/joint_limits.yaml index 3b157b1a..ed1cb087 100644 --- a/assets/robot/openarm_v1.0/config/arm/joint_limits.yaml +++ b/assets/robot/openarm_v1.0/config/arm/joint/joint_limits.yaml @@ -1,4 +1,4 @@ -# Copyright 2025 Enactic, Inc. +# Copyright 2026 Enactic, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,59 +18,39 @@ joint1: upper: 3.490659 velocity: 16.754666 effort: 40 - joint2: limit: lower: -1.745329 upper: 1.745329 velocity: 16.754666 effort: 40 - joint3: limit: lower: -1.570796 upper: 1.570796 velocity: 5.445426 effort: 27 - joint4: limit: lower: 0.0 upper: 2.443461 velocity: 5.445426 effort: 27 - joint5: limit: lower: -1.570796 upper: 1.570796 velocity: 20.943946 effort: 7 - joint6: limit: lower: -0.785398 upper: 0.785398 velocity: 20.943946 effort: 7 - joint7: limit: lower: -1.570796 upper: 1.570796 velocity: 20.943946 effort: 7 - -# joint_gripper1: -# limit: -# lower: 0.0 -# upper: 0.043 -# velocity: 100 -# effort: 100 - -# joint_gripper2: -# limit: -# lower: 0.0 -# upper: 0.043 -# velocity: 100 -# effort: 100 diff --git a/assets/robot/openarm_v1.0/config/arm/kinematics.yaml b/assets/robot/openarm_v1.0/config/arm/joint/joint_origins.yaml similarity index 70% rename from assets/robot/openarm_v1.0/config/arm/kinematics.yaml rename to assets/robot/openarm_v1.0/config/arm/joint/joint_origins.yaml index e6c4df4c..97878685 100644 --- a/assets/robot/openarm_v1.0/config/arm/kinematics.yaml +++ b/assets/robot/openarm_v1.0/config/arm/joint/joint_origins.yaml @@ -1,4 +1,4 @@ -# Copyright 2025 Enactic, Inc. +# Copyright 2026 Enactic, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,91 +13,58 @@ # limitations under the License. joint1: - kinematic: + origin: x: 0.0 y: 0.0 z: 0.0625 roll: 0 pitch: 0 yaw: 0 - joint2: - kinematic: + origin: x: -0.0301 y: 0.0 z: 0.06 roll: 0 pitch: 0 yaw: 0 - joint3: - kinematic: + origin: x: 0.0301 y: 0.0 z: 0.06625 roll: 0 pitch: 0 yaw: 0 - joint4: - kinematic: - x: -0.0 + origin: + x: 0.0 y: 0.0315 z: 0.15375 roll: 0 pitch: 0 yaw: 0 - joint5: - kinematic: + origin: x: 0.0 y: -0.0315 z: 0.0955 roll: 0 pitch: 0 yaw: 0 - joint6: - kinematic: + origin: x: 0.0375 y: 0.0 z: 0.1205 roll: 0 pitch: 0 yaw: 0 - -# joint7: -# kinematic: -# x: -0.0375 -# y: 0.0205 -# z: 0.0 -# roll: 0 -# pitch: 0 -# yaw: 0 - joint7: - kinematic: + origin: x: -0.0375 y: 0.0 z: 0.0 roll: 0 pitch: 0 yaw: 0 - -# joint8: -# kinematic: -# x: 1e-06 -# y: -0.098 -# z: 0.114501 -# roll: 0 -# pitch: 0 -# yaw: 0 - -joint8: - kinematic: - x: 1e-06 - y: 0.0205 - z: 0.0 - roll: 0 - pitch: 0 - yaw: 0 diff --git a/assets/robot/openarm_v1.0/config/arm/kinematics_link.yaml b/assets/robot/openarm_v1.0/config/arm/kinematics_link.yaml deleted file mode 100644 index f31da1b3..00000000 --- a/assets/robot/openarm_v1.0/config/arm/kinematics_link.yaml +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2025 Enactic, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -link0: - kinematic: - x: 0.0 - y: 0.0 - z: 0.0 - roll: 0.0 - pitch: 0.0 - yaw: 0.0 - -link1: - kinematic: - x: -0.0 - y: 0.0 - z: -0.0625 - roll: 0.0 - pitch: 0.0 - yaw: 0.0 - -link2: - kinematic: - x: 0.0301 - y: 0.0 - z: -0.1225 - roll: 0.0 - pitch: 0.0 - yaw: 0.0 - -link3: - kinematic: - x: -0.0 - y: -0.0 - z: -0.18875 - roll: 0.0 - pitch: 0.0 - yaw: 0.0 - -link4: - kinematic: - x: 0.0 - y: -0.0315 - z: -0.3425 - roll: 0.0 - pitch: 0.0 - yaw: 0.0 - -link5: - kinematic: - x: -0.0 - y: -0.0 - z: -0.438 - roll: 0.0 - pitch: 0.0 - yaw: 0.0 - -link6: - kinematic: - x: -0.0375 - y: -0.0 - z: -0.5585 - roll: 0.0 - pitch: 0.0 - yaw: 0.0 - -# link7: -# kinematic: -# x: 0.0 -# y: -0.0205 -# z: -0.5585 -# roll: 0.0 -# pitch: 0.0 -# yaw: 0.0 - -link7: - kinematic: - x: 0.0 - y: -0.0 - z: -0.5585 - roll: 0.0 - pitch: 0.0 - yaw: 0.0 diff --git a/assets/robot/openarm_v1.0/config/arm/kinematics_offset.yaml b/assets/robot/openarm_v1.0/config/arm/kinematics_offset.yaml deleted file mode 100644 index 315720bb..00000000 --- a/assets/robot/openarm_v1.0/config/arm/kinematics_offset.yaml +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright 2025 Enactic, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -joint1: - kinematic_offset: - x: 0.0 - y: 0.0 - z: 0.0 - roll: 0 - pitch: 0 - yaw: 0 - -joint2: - kinematic_offset: - x: 0.0 - y: 0.0 - z: 0.0 - roll: 1.57079632679 - pitch: 0 - yaw: 0 - -joint3: - kinematic_offset: - x: 0.0 - y: 0.0 - z: 0.0 - roll: 0 - pitch: 0 - yaw: 0 - -joint4: - kinematic_offset: - x: -0.0 - y: 0.0 - z: 0.0 - roll: 0 - pitch: 0 - yaw: 0 - -joint5: - kinematic_offset: - x: 0.0 - y: -0.0 - z: 0.0 - roll: 0 - pitch: 0 - yaw: 0 - -joint6: - kinematic_offset: - x: 0.0 - y: 0.0 - z: 0.0 - roll: 0 - pitch: 0 - yaw: 0 - -joint7: - kinematic_offset: - x: -0.0 - y: 0.0 - z: 0.0 - roll: 0 - pitch: 0 - yaw: 0 - -joint8: - kinematic_offset: - x: 0.0 - y: -0.0 - z: 0.0 - roll: 0 - pitch: 0 - yaw: 0 diff --git a/assets/robot/openarm_v1.0/config/arm/link/collisions.yaml b/assets/robot/openarm_v1.0/config/arm/link/collisions.yaml new file mode 100644 index 00000000..f2860d07 --- /dev/null +++ b/assets/robot/openarm_v1.0/config/arm/link/collisions.yaml @@ -0,0 +1,112 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +link1: + origin: + x: 0.0 + y: 0.0 + z: 0.0 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/collision/link0_symp.stl + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link2: + origin: + x: -0.0 + y: 0.0 + z: -0.0625 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/collision/link1_symp.stl + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link3: + origin: + x: 0.0301 + y: 0.0 + z: -0.1225 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/collision/link2_symp.stl + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link4: + origin: + x: -0.0 + y: -0.0 + z: -0.18875 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/collision/link3_symp.stl + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link5: + origin: + x: 0.0 + y: -0.0315 + z: -0.3425 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/collision/link4_symp.stl + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link6: + origin: + x: -0.0 + y: -0.0 + z: -0.438 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/collision/link5_symp.stl + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link7: + origin: + x: -0.0375 + y: 0.0 + z: -0.5585 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/collision/link6_symp.stl + scale: + x: 0.001 + y: 0.001 + z: 0.001 diff --git a/assets/robot/openarm_v1.0/config/arm/link/visuals.yaml b/assets/robot/openarm_v1.0/config/arm/link/visuals.yaml new file mode 100644 index 00000000..2e09913f --- /dev/null +++ b/assets/robot/openarm_v1.0/config/arm/link/visuals.yaml @@ -0,0 +1,112 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +link1: + origin: + x: 0.0 + y: 0.0 + z: 0.0 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/visual/link0.dae + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link2: + origin: + x: -0.0 + y: 0.0 + z: -0.0625 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/visual/link1.dae + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link3: + origin: + x: 0.0301 + y: 0.0 + z: -0.1225 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/visual/link2.dae + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link4: + origin: + x: -0.0 + y: -0.0 + z: -0.18875 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/visual/link3.dae + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link5: + origin: + x: 0.0 + y: -0.0315 + z: -0.3425 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/visual/link4.dae + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link6: + origin: + x: -0.0 + y: -0.0 + z: -0.438 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/visual/link5.dae + scale: + x: 0.001 + y: 0.001 + z: 0.001 +link7: + origin: + x: -0.0375 + y: 0.0 + z: -0.5585 + roll: 0.0 + pitch: 0.0 + yaw: 0.0 + geometry: + mesh: package://openarm_description/assets/robot/openarm_v1.0/mesh/arm/visual/link6.dae + scale: + x: 0.001 + y: 0.001 + z: 0.001 diff --git a/assets/robot/openarm_v1.0/config/arm/struct/name_mapping.yaml b/assets/robot/openarm_v1.0/config/arm/struct/name_mapping.yaml new file mode 100644 index 00000000..d7f87fa7 --- /dev/null +++ b/assets/robot/openarm_v1.0/config/arm/struct/name_mapping.yaml @@ -0,0 +1,33 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +links: + canonical_to_original: + link1: link0 + link2: link1 + link3: link2 + link4: link3 + link5: link4 + link6: link5 + link7: link6 + link8: arm_end_link +joints: + canonical_to_original: + joint1: joint1 + joint2: joint2 + joint3: joint3 + joint4: joint4 + joint5: joint5 + joint6: joint6 + joint7: joint7 diff --git a/assets/robot/openarm_v1.0/config/arm/struct/reference_points.yaml b/assets/robot/openarm_v1.0/config/arm/struct/reference_points.yaml new file mode 100644 index 00000000..1f6d008b --- /dev/null +++ b/assets/robot/openarm_v1.0/config/arm/struct/reference_points.yaml @@ -0,0 +1,24 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ee_mount_point: + parent: link8 + emit: false + origin: + x: 0 + y: 0 + z: 0 + roll: 0 + pitch: 0 + yaw: 0 diff --git a/assets/robot/openarm_v1.0/config/arm/struct/topology.yaml b/assets/robot/openarm_v1.0/config/arm/struct/topology.yaml new file mode 100644 index 00000000..dd54172a --- /dev/null +++ b/assets/robot/openarm_v1.0/config/arm/struct/topology.yaml @@ -0,0 +1,61 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +collapse_empty_end: true +links: + link1: + name: link0 + link2: + name: link1 + link3: + name: link2 + link4: + name: link3 + link5: + name: link4 + link6: + name: link5 + link7: + name: link6 + link8: + name: arm_end_link +joints: + joint1: + type: revolute + parent: link1 + child: link2 + joint2: + type: revolute + parent: link2 + child: link3 + joint3: + type: revolute + parent: link3 + child: link4 + joint4: + type: revolute + parent: link4 + child: link5 + joint5: + type: revolute + parent: link5 + child: link6 + joint6: + type: revolute + parent: link6 + child: link7 + joint7: + type: revolute + parent: link7 + child: link8 diff --git a/assets/robot/openarm_v1.0/config/robot_presets/default_bimanual.yaml b/assets/robot/openarm_v1.0/config/robot_presets/default_bimanual.yaml new file mode 100644 index 00000000..133b9e0f --- /dev/null +++ b/assets/robot/openarm_v1.0/config/robot_presets/default_bimanual.yaml @@ -0,0 +1,174 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +robot: + root_frame: world + components: + - body + - primary_arm + - secondary_arm + - primary_arm_end_effector + - secondary_arm_end_effector +body: + type: body + prefix: openarm_ + enabled: true + product: v1.0 + config: null + inertials: nominal + connection: + parent: world + origin: + x: 0 + y: 0 + z: 0 + roll: 0 + pitch: 0 + yaw: 0 +primary_arm: + type: robot + enabled: true + product: openarm_v1.0 + config: arm + inertials: nominal + prefix: openarm_left_ + connection: + attach_to: body + parent_reference_point: left_arm_mount_point + reflect: + x: 1 + y: -1 + z: 1 + include: + links: + - link1 + - link2 + - link3 + - link6 + - link7 + - link8 + joints: + - joint1 + - joint2 + - joint3 + - joint6 + - joint7 + reference_points: + - ee_mount_point + origin_override_joints: + joint2: + x: -0.0301 + y: 0.0 + z: 0.06 + roll: 1.57079632679 + pitch: 0 + yaw: 0 + limit_override_joints: + joint2: + lower: -0.17453267320510335 + upper: 3.3161253267948965 + velocity: 16.754666 + effort: 40 +primary_arm_end_effector: + type: end_effector + enabled: true + product: parallel_link + config: null + inertials: nominal + prefix: openarm_left_ + connection: + attach_to: primary_arm + parent_reference_point: ee_mount_point + reflect: + x: 1 + y: -1 + z: 1 + include: + links: + - link1 + joints: [] + reference_points: [] +secondary_arm: + type: robot + enabled: true + product: openarm_v1.0 + config: arm + inertials: nominal + prefix: openarm_right_ + connection: + attach_to: body + parent_reference_point: right_arm_mount_point + reflect: + x: 1 + y: 1 + z: 1 + origin_override_joints: + joint2: + x: -0.0301 + y: 0.0 + z: 0.06 + roll: 1.57079632679 + pitch: 0 + yaw: 0 + limit_override_joints: + joint2: + lower: -0.17453267320510335 + upper: 3.3161253267948965 + velocity: 16.754666 + effort: 40 +secondary_arm_end_effector: + type: end_effector + enabled: true + product: parallel_link + config: null + inertials: nominal + prefix: openarm_right_ + connection: + attach_to: secondary_arm + parent_reference_point: ee_mount_point + reflect: + x: 1 + y: 1 + z: 1 + include: + links: + - link1 + joints: [] + reference_points: [] + +systems: + openarm_left_hardware_interface: + joints: + primary_arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} + primary_arm_end_effector: + joint2: {idx: 8} + openarm_right_hardware_interface: + joints: + secondary_arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} + secondary_arm_end_effector: + joint2: {idx: 8} diff --git a/assets/robot/openarm_v1.0/config/robot_presets/default_single.yaml b/assets/robot/openarm_v1.0/config/robot_presets/default_single.yaml new file mode 100644 index 00000000..64ac1654 --- /dev/null +++ b/assets/robot/openarm_v1.0/config/robot_presets/default_single.yaml @@ -0,0 +1,72 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +robot: + root_frame: world + components: + - arm + - end_effector +arm: + type: robot + enabled: true + product: openarm_v1.0 + config: arm + inertials: nominal + prefix: openarm_ + connection: + parent: world + origin: + x: 0 + y: 0 + z: 0 + roll: 0 + pitch: 0 + yaw: 0 + reflect: + x: 1 + y: 1 + z: 1 +end_effector: + type: end_effector + enabled: true + product: parallel_link + config: null + inertials: nominal + prefix: openarm_ + connection: + attach_to: arm + parent_reference_point: ee_mount_point + reflect: + x: 1 + y: 1 + z: 1 + include: + links: + - link1 + joints: [] + reference_points: [] + +systems: + openarm_hardware_interface: + joints: + arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} + end_effector: + joint2: {idx: 8} diff --git a/assets/robot/openarm_v1.0/config/robot_presets/left_arm.yaml b/assets/robot/openarm_v1.0/config/robot_presets/left_arm.yaml new file mode 100644 index 00000000..3081a852 --- /dev/null +++ b/assets/robot/openarm_v1.0/config/robot_presets/left_arm.yaml @@ -0,0 +1,66 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +robot: + root_frame: world + components: + - arm +arm: + type: robot + enabled: true + product: openarm_v1.0 + config: arm + inertials: nominal + prefix: openarm_left_ + connection: + parent: world + origin: + x: 0 + y: 0 + z: 0 + roll: 0 + pitch: 0 + yaw: 0 + reflect: + x: 1 + y: -1 + z: 1 + include: + links: + - link1 + - link2 + - link3 + - link6 + - link7 + - link8 + joints: + - joint1 + - joint2 + - joint3 + - joint6 + - joint7 + reference_points: + - ee_mount_point + +systems: + openarm_left_hardware_interface: + joints: + arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} diff --git a/assets/robot/openarm_v1.0/config/robot_presets/left_arm_with_parallel_link.yaml b/assets/robot/openarm_v1.0/config/robot_presets/left_arm_with_parallel_link.yaml new file mode 100644 index 00000000..003f55de --- /dev/null +++ b/assets/robot/openarm_v1.0/config/robot_presets/left_arm_with_parallel_link.yaml @@ -0,0 +1,88 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +robot: + root_frame: world + components: + - arm + - end_effector +arm: + type: robot + enabled: true + product: openarm_v1.0 + config: arm + inertials: nominal + prefix: openarm_left_ + connection: + parent: world + origin: + x: 0 + y: 0 + z: 0 + roll: 0 + pitch: 0 + yaw: 0 + reflect: + x: 1 + y: -1 + z: 1 + include: + links: + - link1 + - link2 + - link3 + - link6 + - link7 + - link8 + joints: + - joint1 + - joint2 + - joint3 + - joint6 + - joint7 + reference_points: + - ee_mount_point +end_effector: + type: end_effector + enabled: true + product: parallel_link + config: null + inertials: nominal + prefix: openarm_left_ + connection: + attach_to: arm + parent_reference_point: ee_mount_point + reflect: + x: 1 + y: -1 + z: 1 + include: + links: + - link1 + joints: [] + reference_points: [] + +systems: + openarm_left_hardware_interface: + joints: + arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} + end_effector: + joint2: {idx: 8} diff --git a/assets/robot/openarm_v1.0/config/robot_presets/right_arm.yaml b/assets/robot/openarm_v1.0/config/robot_presets/right_arm.yaml new file mode 100644 index 00000000..e4f0eddd --- /dev/null +++ b/assets/robot/openarm_v1.0/config/robot_presets/right_arm.yaml @@ -0,0 +1,50 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +robot: + root_frame: world + components: + - arm +arm: + type: robot + enabled: true + product: openarm_v1.0 + config: arm + inertials: nominal + prefix: openarm_right_ + connection: + parent: world + origin: + x: 0 + y: 0 + z: 0 + roll: 0 + pitch: 0 + yaw: 0 + reflect: + x: 1 + y: 1 + z: 1 + +systems: + openarm_right_hardware_interface: + joints: + arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} diff --git a/assets/robot/openarm_v1.0/config/robot_presets/right_arm_with_parallel_link.yaml b/assets/robot/openarm_v1.0/config/robot_presets/right_arm_with_parallel_link.yaml new file mode 100644 index 00000000..132855e2 --- /dev/null +++ b/assets/robot/openarm_v1.0/config/robot_presets/right_arm_with_parallel_link.yaml @@ -0,0 +1,72 @@ +# Copyright 2026 Enactic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +robot: + root_frame: world + components: + - arm + - end_effector +arm: + type: robot + enabled: true + product: openarm_v1.0 + config: arm + inertials: nominal + prefix: openarm_right_ + connection: + parent: world + origin: + x: 0 + y: 0 + z: 0 + roll: 0 + pitch: 0 + yaw: 0 + reflect: + x: 1 + y: 1 + z: 1 +end_effector: + type: end_effector + enabled: true + product: parallel_link + config: null + inertials: nominal + prefix: openarm_right_ + connection: + attach_to: arm + parent_reference_point: ee_mount_point + reflect: + x: 1 + y: 1 + z: 1 + include: + links: + - link1 + joints: [] + reference_points: [] + +systems: + openarm_right_hardware_interface: + joints: + arm: + joint1: {idx: 1} + joint2: {idx: 2} + joint3: {idx: 3} + joint4: {idx: 4} + joint5: {idx: 5} + joint6: {idx: 6} + joint7: {idx: 7} + end_effector: + joint2: {idx: 8} diff --git a/assets/robot/openarm_v1.0/urdf/arm/openarm_arm.xacro b/assets/robot/openarm_v1.0/urdf/arm/openarm_arm.xacro deleted file mode 100644 index 3567a9dc..00000000 --- a/assets/robot/openarm_v1.0/urdf/arm/openarm_arm.xacro +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/robot/openarm_v1.0/urdf/arm/openarm_macro.xacro b/assets/robot/openarm_v1.0/urdf/arm/openarm_macro.xacro deleted file mode 100644 index ca530c7b..00000000 --- a/assets/robot/openarm_v1.0/urdf/arm/openarm_macro.xacro +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - ${xacro.warning('No inertia properties defined for: ' + name)} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - openarm_hw/openarmStateInterface - - - - - - openarm_hw/openarmModelInterface - - root - openarm_hw/openarmModelInterface - - - tip - openarm_hw/openarmModelInterface - - openarm_hw/openarmModelInterface - openarm_hw/openarmModelInterface - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/robot/openarm_v1.0/urdf/body/openarm_body.xacro b/assets/robot/openarm_v1.0/urdf/body/openarm_body.xacro deleted file mode 100644 index d3fada87..00000000 --- a/assets/robot/openarm_v1.0/urdf/body/openarm_body.xacro +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/robot/openarm_v1.0/urdf/body/openarm_body_macro.xacro b/assets/robot/openarm_v1.0/urdf/body/openarm_body_macro.xacro deleted file mode 100644 index 3b200efa..00000000 --- a/assets/robot/openarm_v1.0/urdf/body/openarm_body_macro.xacro +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - ${xacro.warning('No inertia properties defined for: ' + name)} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/robot/openarm_v1.0/urdf/ee/ee_dispatcher.xacro b/assets/robot/openarm_v1.0/urdf/ee/ee_dispatcher.xacro deleted file mode 100644 index 7f811804..00000000 --- a/assets/robot/openarm_v1.0/urdf/ee/ee_dispatcher.xacro +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - ${xacro.error('assets/robot/openarm_v1.0 only supports ee_type:=parallel_link.')} - - - diff --git a/assets/robot/openarm_v1.0/urdf/ee/openarm_ee_macro.xacro b/assets/robot/openarm_v1.0/urdf/ee/openarm_ee_macro.xacro deleted file mode 100644 index 425d08d2..00000000 --- a/assets/robot/openarm_v1.0/urdf/ee/openarm_ee_macro.xacro +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - ${xacro.warning('No inertia properties defined for: ' + name)} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/robot/openarm_v1.0/urdf/ee/parallel_link/openarm_parallel_gripper.xacro b/assets/robot/openarm_v1.0/urdf/ee/parallel_link/openarm_parallel_gripper.xacro deleted file mode 100644 index 6a00c3a2..00000000 --- a/assets/robot/openarm_v1.0/urdf/ee/parallel_link/openarm_parallel_gripper.xacro +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/robot/openarm_v1.0/urdf/ee/pinch_gripper/openarm_v20_pinch_gripper.xacro b/assets/robot/openarm_v1.0/urdf/ee/pinch_gripper/openarm_v20_pinch_gripper.xacro deleted file mode 100644 index 6d366553..00000000 --- a/assets/robot/openarm_v1.0/urdf/ee/pinch_gripper/openarm_v20_pinch_gripper.xacro +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/robot/openarm_v1.0/urdf/example/v1.urdf b/assets/robot/openarm_v1.0/urdf/example/v1.urdf index 7b8865cd..bec33afe 100644 --- a/assets/robot/openarm_v1.0/urdf/example/v1.urdf +++ b/assets/robot/openarm_v1.0/urdf/example/v1.urdf @@ -4,7 +4,7 @@ - - - - - - + + - + - + - - + - + - - - - + + + + - + + - + - - + + + + + + - + + - + - - + - + - + - + + - + - - + - + @@ -124,6 +124,7 @@ limitations under the License. + @@ -132,7 +133,6 @@ limitations under the License. - @@ -142,7 +142,7 @@ limitations under the License. - + @@ -151,6 +151,7 @@ limitations under the License. + @@ -159,7 +160,6 @@ limitations under the License. - @@ -169,7 +169,7 @@ limitations under the License. - + @@ -177,20 +177,20 @@ limitations under the License. - + + - + - - + @@ -204,66 +204,148 @@ limitations under the License. - + + - + - - + - + + + + + + + + - + + - + - + - - + - + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -272,7 +354,6 @@ limitations under the License. - @@ -281,9 +362,15 @@ limitations under the License. + + + + + + @@ -292,7 +379,6 @@ limitations under the License. - @@ -311,6 +397,7 @@ limitations under the License. + @@ -319,7 +406,6 @@ limitations under the License. - @@ -338,6 +424,7 @@ limitations under the License. + @@ -346,7 +433,6 @@ limitations under the License. - @@ -365,6 +451,7 @@ limitations under the License. + @@ -373,7 +460,6 @@ limitations under the License. - @@ -383,7 +469,7 @@ limitations under the License. - + @@ -392,6 +478,7 @@ limitations under the License. + @@ -400,7 +487,6 @@ limitations under the License. - @@ -418,16 +504,16 @@ limitations under the License. - + + - + - @@ -443,41 +529,42 @@ limitations under the License. + + + + + + + - + + - + - + - - + - + - + - - - - - - - - - + + + - + @@ -486,47 +573,23 @@ limitations under the License. - + - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - + + + - + @@ -538,54 +601,17 @@ limitations under the License. - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -602,38 +628,18 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + diff --git a/assets/robot/openarm_v1.0/urdf/openarm_v10.urdf.xacro b/assets/robot/openarm_v1.0/urdf/openarm_v10.urdf.xacro index 4b72af3a..1b711e0d 100644 --- a/assets/robot/openarm_v1.0/urdf/openarm_v10.urdf.xacro +++ b/assets/robot/openarm_v1.0/urdf/openarm_v10.urdf.xacro @@ -1,6 +1,6 @@ - + - - + + - - - - + + - - - - - - - - - - - - - - ${xacro.error('assets/robot/openarm_v1.0 supports arm_type in ' + str(accepted_arm_types) + ' (got: $(arg arm_type)). Use assets/robot/openarm_v2.0 for newer hardware variants.')} - - - ${xacro.error('assets/robot/openarm_v1.0 only supports body_type:=v10.')} - - - - - - + + - ee_inertials="${xacro.load_yaml(parallel_link_cfg_root + '/inertials.yaml')}" - ee_kinematics="${xacro.load_yaml(parallel_link_cfg_root + '/kinematics.yaml')}" - ee_kinematics_link="${xacro.load_yaml(parallel_link_cfg_root + '/kinematics_link.yaml')}" - ee_joints_limits="${xacro.load_yaml(parallel_link_cfg_root + '/joint_limits.yaml')}" - ee_type="parallel_link" - - ros2_control="$(arg ros2_control)" - can_interface="$(arg can_interface)" - left_can_interface="$(arg left_can_interface)" - right_can_interface="$(arg right_can_interface)" - left_arm_prefix="$(arg left_arm_prefix)" - right_arm_prefix="$(arg right_arm_prefix)" - use_fake_hardware="$(arg use_fake_hardware)" - fake_sensor_commands="$(arg fake_sensor_commands)" - no_prefix="$(arg no_prefix)" - arm_prefix="" - body_prefix="" - arm_connected_to="base" - body_connected_to="world" - bimanual="$(arg bimanual)" - right_arm_base_xyz="$(arg right_arm_base_xyz)" - left_arm_base_xyz="$(arg left_arm_base_xyz)" - right_arm_base_rpy="$(arg right_arm_base_rpy)" - left_arm_base_rpy="$(arg left_arm_base_rpy)" - can_fd="$(arg can_fd)" - /> + + + + + + + + + + + + + + + diff --git a/assets/robot/openarm_v1.0/urdf/robot/openarm_robot.xacro b/assets/robot/openarm_v1.0/urdf/robot/openarm_robot.xacro deleted file mode 100644 index 41824fa6..00000000 --- a/assets/robot/openarm_v1.0/urdf/robot/openarm_robot.xacro +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/robot/openarm_v1.0/urdf/ros2_control/openarm.bimanual.ros2_control.xacro b/assets/robot/openarm_v1.0/urdf/ros2_control/openarm.bimanual.ros2_control.xacro deleted file mode 100644 index 999b443a..00000000 --- a/assets/robot/openarm_v1.0/urdf/ros2_control/openarm.bimanual.ros2_control.xacro +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - - - - - - ${arm_type} - - mock_components/GenericSystem - ${fake_sensor_commands} - 0.0 - - - openarm_hardware/OpenArmHW - ${left_can_interface} - ${left_arm_prefix} - ${hand} - ${can_fd} - ${ee_type} - ${control_gains['joint1']['kp']} - ${control_gains['joint2']['kp']} - ${control_gains['joint3']['kp']} - ${control_gains['joint4']['kp']} - ${control_gains['joint5']['kp']} - ${control_gains['joint6']['kp']} - ${control_gains['joint7']['kp']} - ${control_gains['joint1']['kd']} - ${control_gains['joint2']['kd']} - ${control_gains['joint3']['kd']} - ${control_gains['joint4']['kd']} - ${control_gains['joint5']['kd']} - ${control_gains['joint6']['kd']} - ${control_gains['joint7']['kd']} - - ${control_gains['hand']['kp']} - ${control_gains['hand']['kd']} - - - - - - - - - - - - ${initial_position} - - - - 0.0 - - - - 0.0 - - - - - - - - - - - - - - - - - - - - - ${arm_type} - - mock_components/GenericSystem - ${fake_sensor_commands} - 0.0 - - - openarm_hardware/OpenArmHW - ${right_can_interface} - ${right_arm_prefix} - ${hand} - ${can_fd} - ${ee_type} - ${control_gains['joint1']['kp']} - ${control_gains['joint2']['kp']} - ${control_gains['joint3']['kp']} - ${control_gains['joint4']['kp']} - ${control_gains['joint5']['kp']} - ${control_gains['joint6']['kp']} - ${control_gains['joint7']['kp']} - ${control_gains['joint1']['kd']} - ${control_gains['joint2']['kd']} - ${control_gains['joint3']['kd']} - ${control_gains['joint4']['kd']} - ${control_gains['joint5']['kd']} - ${control_gains['joint6']['kd']} - ${control_gains['joint7']['kd']} - - ${control_gains['hand']['kp']} - ${control_gains['hand']['kd']} - - - - - - - - - - - - - - - - - - - - diff --git a/assets/robot/openarm_v1.0/urdf/ros2_control/openarm.ros2_control.xacro b/assets/robot/openarm_v1.0/urdf/ros2_control/openarm.ros2_control.xacro deleted file mode 100644 index 97cc630c..00000000 --- a/assets/robot/openarm_v1.0/urdf/ros2_control/openarm.ros2_control.xacro +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - ${arm_type} - ${arm_prefix} - - mock_components/GenericSystem - ${fake_sensor_commands} - 0.0 - - - openarm_hardware/OpenArmHW - ${can_interface} - ${arm_prefix} - ${hand} - ${can_fd} - ${ee_type} - ${control_gains['joint1']['kp']} - ${control_gains['joint2']['kp']} - ${control_gains['joint3']['kp']} - ${control_gains['joint4']['kp']} - ${control_gains['joint5']['kp']} - ${control_gains['joint6']['kp']} - ${control_gains['joint7']['kp']} - ${control_gains['joint1']['kd']} - ${control_gains['joint2']['kd']} - ${control_gains['joint3']['kd']} - ${control_gains['joint4']['kd']} - ${control_gains['joint5']['kd']} - ${control_gains['joint6']['kd']} - ${control_gains['joint7']['kd']} - - - - - - - - - - - - - ${initial_position} - - - - 0.0 - - - - 0.0 - - - - - - - - - - - - - - - - - - - - - - - diff --git a/launch/display_openarm.launch.py b/launch/display_openarm.launch.py index 4471cff7..c5c107d2 100644 --- a/launch/display_openarm.launch.py +++ b/launch/display_openarm.launch.py @@ -74,6 +74,7 @@ def robot_state_publisher_spawner( "arm_type": arm_type_str, "body_type": "v10", "bimanual": context.perform_substitution(bimanual), + "robot_preset": context.perform_substitution(robot_preset), "ros2_control": context.perform_substitution(ros2_control), "use_fake_hardware": context.perform_substitution(use_fake_hardware), "fake_sensor_commands": context.perform_substitution(fake_sensor_commands), @@ -81,7 +82,7 @@ def robot_state_publisher_spawner( else: mappings = { "arm_type": arm_type_str, - "robot_preset": context.perform_substitution(robot_preset), + "robot_preset": context.perform_substitution(robot_preset) or "default_bimanual", "emit_grasp_frame": context.perform_substitution(emit_grasp_frame), "ros2_control": context.perform_substitution(ros2_control), "use_fake_hardware": context.perform_substitution(use_fake_hardware), @@ -112,8 +113,8 @@ def generate_launch_description(): ) robot_preset_arg = DeclareLaunchArgument( "robot_preset", - default_value="default_bimanual", - description="Robot preset for v2.0 (e.g. default_bimanual, right_arm, left_arm).", + default_value="", + description="Robot preset; empty selects the default assembly for the selected version.", ) rviz_config_arg = DeclareLaunchArgument( "rviz_config", diff --git a/test/test_entrypoints.py b/test/test_entrypoints.py index 4fb33c37..e618f95b 100644 --- a/test/test_entrypoints.py +++ b/test/test_entrypoints.py @@ -16,7 +16,7 @@ import xacro import yaml -from support import expand, multiply, near, pinch, pose, transform +from support import expand, model, multiply, near, pinch, pose, transform def write_configuration(directory, data): @@ -26,6 +26,20 @@ def write_configuration(directory, data): path.write_text(yaml.safe_dump(value, sort_keys=False)) +def test_parallel_entry_forwards_tcp_arguments(tmp_path): + data = model(('link7',)) + data['struct/reference_points.yaml'] = { + 'hand_tcp': dict(parent='link7', emit=True, origin=pose(z=.4))} + write_configuration(tmp_path, data) + robot = expand(entry='assets/end_effector/parallel_link/urdf/parallel_link_standalone.urdf.xacro', + ee_config_dir=tmp_path, reflect_y=-1, tcp_xyz='.01 .02 .10', tcp_rpy='.2 .3 .4') + joint = robot.find("joint[@name='hand_tcp_joint']") + assert joint.find('parent').get( + 'link') == data['struct/reference_points.yaml']['hand_tcp']['parent'] + near(transform(joint.find('origin')), + transform(pose(.01, .02, .1, .2, .3, .4))) + + def test_pinch_entry_forwards_reference_options(tmp_path): data = pinch() reference = dict(parent='link1', emit=True, diff --git a/test/test_models.py b/test/test_models.py index 57716a88..46ae330d 100644 --- a/test/test_models.py +++ b/test/test_models.py @@ -20,7 +20,7 @@ def test_shipped_presets_expand_and_resolve_resources(): robots = [] - for version in ('v2.0',): + for version in ('v1.0', 'v2.0'): folder = ROOT/f'assets/robot/openarm_{version}/config/robot_presets' robots.append((version, '', expand(version=version, ros2_control=True, use_fake_hardware=True, emit_grasp_frame=True))) @@ -28,7 +28,7 @@ def test_shipped_presets_expand_and_resolve_resources(): robot = expand(version=version, robot_preset=path.stem, ros2_control=True, use_fake_hardware=True, emit_grasp_frame=True) robots.append((version, path.stem, robot)) - for path in sorted((ROOT/'assets/end_effector').glob('pinch_gripper/urdf/*_standalone.urdf.xacro')): + for path in sorted((ROOT/'assets/end_effector').glob('*/urdf/*_standalone.urdf.xacro')): robots.append(('standalone', path.name, expand( entry=str(path.relative_to(ROOT))))) for version, name, robot in robots: