5.1.8 End Effector Control

Note

X2 EDU does not support the features in this section. This section applies only to X2 Ultra and X2 Ultra(new version).

The end-effector control module currently supports:

  • Dexterous Hand: OmniHand Dynamic Edition 2025

  • Gripper: OmniPicker

Control Methods

The end-effector offers two control methods. Choose based on your application scenario:

  • Recommended: Upper Body Control (non-low-level control): Integrates the end-effector into the upper body control framework via UPPERBODY_REMOTE_SPLIT mode to control head, arms, and hands together. The native MC module retains functions such as locomotion management; no manual stop is required.

  • Low-level control: Send HandCommandArray commands directly to the hand via the /aima/hal/joint/hand/command topic. Requires running aima em stop-app mc on the Motion Control Computing Unit (PC1) to prevent the native MC module from taking over the hand. Suitable for scenarios where independent hand control is needed without the upper body control framework.

Attention

Before using low-level control, ensure the robot is in a safe state and run aima em stop-app mc on the Motion Control Computing Unit (PC1) to prevent the native MC module from controlling the hand.

The following sections detail the low-level control interface. For upper body control usage, see Upper Body Control.

Low-level Control Interface

Hand Control Features

  • Dexterous Hand Mode: Supports multi-finger coordinated control, suitable for complex manipulation.

  • Gripper Mode: Supports open/close control, suitable for simple grasping.

  • Status Monitoring: Real-time monitoring of hand status and fault codes.

  • Type Query: Supports dynamic querying of the current hand type.

Hand Control Topics

Topic Name

Data Type

Description

QoS

Frequency

/aima/hal/joint/hand/command

HandCommandArray

Hand control command

BEST_EFFORT+VOLATILE

User (on-demand)

  • HandCommandArray ros2-msg @ hal/msg/HandCommandArray.msg

    # Hand command array
    MessageHeader header             # Message header
    HandType left_hand_type          # Left hand type (left_hand_type.value: 1 (NIMBLE_HANDS dexterous hand), 2 (CLAW gripper))
    HandCommand[] left_hands         # Left hand commands
    HandType right_hand_type         # Right hand type (right_hand_type.value: 1 (NIMBLE_HANDS dexterous hand), 2 (CLAW gripper))
    HandCommand[] right_hands        # Right hand commands
    

    Valid HandType values are 1 (NIMBLE_HANDS) and 2 (CLAW). Passing 0 (NONE), 0xFF (ERROR), or other values will cause the command to be silently dropped without execution or error response.

    Notes on HandCommand[] length and ordering:

    Hand Type

    Array Length

    Order

    Gripper OmniPicker

    1

    N/A

    Dexterous Hand OmniHand

    10

    Ordered by active-axis index; see joint index-to-name mapping

    name is for debugging only and may change across versions. Identify joints by array index order, do not rely on name field matching. Current name-to-index mapping:

    Index

    name (Left)

    name (Right)

    0

    L_thumb_roll_joint

    R_thumb_roll_joint

    1

    L_thumb_abad_joint

    R_thumb_abad_joint

    2

    L_thumb_mcp_joint

    R_thumb_mcp_joint

    3

    L_index_abad_joint

    R_index_abad_joint

    4

    L_index_pip_joint

    R_index_pip_joint

    5

    L_middle_pip_joint

    R_middle_pip_joint

    6

    L_ring_abad_joint

    R_ring_abad_joint

    7

    L_ring_pip_joint

    R_ring_pip_joint

    8

    L_pinky_abad_joint

    R_pinky_abad_joint

    9

    L_pinky_pip_joint

    R_pinky_pip_joint

    • HandCommand ros2-msg @ hal/msg/HandCommand.msg

      # Hand control command
      string name                      # Joint name
      float64 position                 # Position
      float64 velocity                 # Velocity
      float64 acceleration             # Acceleration
      float64 deceleration             # Deceleration
      float64 effort                   # Effort / torque
      

      Note: The meaning and value range of these fields varies significantly depending on the hand type:

      • Gripper OmniPicker:

        Field Name

        Value Range

        Description

        position

        0.0-1.0

        Linearly maps gripper open/close travel; 1.0 = fully open

        velocity

        0.0-1.0

        Linearly maps gripper speed; 1.0 = maximum speed

        acceleration

        0.0-1.0

        Linearly maps gripper acceleration; 1.0 = maximum acceleration

        deceleration

        0.0-1.0

        Linearly maps gripper deceleration; 1.0 = maximum deceleration

        effort

        0.0-1.0

        Linearly maps gripper holding torque; 1.0 = maximum torque

      • Dexterous Hand OmniHand:

        Field Name

        Value Range

        Description

        position

        Active joint range (unit: rad)

        Current position

        velocity

        N/A

        Not used

        acceleration

        N/A

        Not used

        deceleration

        N/A

        Not used

        effort

        N/A

        Not used

        Note

        OmniHand low-level control currently only supports position commands (position); velocity/effort/acceleration/deceleration are not yet enabled. For force-position hybrid control and other advanced modes, use Upper Body Control.

Attention

Before using low-level control, run aima em stop-app mc on the Motion Control Computing Unit (PC1) to prevent the native MC module from taking over the hand.

Hand Status Topics

Topic Name

Data Type

Description

QoS

Frequency

/aima/hal/joint/hand/state

HandStateArray

Hand status information

BEST_EFFORT+TRANSIENT_LOCAL

200 Hz (low scheduling priority; frequency drops under load)

  • HandStateArray ros2-msg @ hal/msg/HandStateArray.msg

    # Hand status array
    MessageHeader header                          # Message header
    HandType left_hand_type                       # Left hand type
    HandState[] left_hands                        # Left hand states
    HandTouchSensorData left_touch_sensors        # Left hand touch sensor data
    HandType right_hand_type                      # Right hand type
    HandState[] right_hands                       # Right hand states
    HandTouchSensorData right_touch_sensors       # Right hand touch sensor data
    

    Values:

    Value

    Description

    Data Validity

    1 (NIMBLE_HANDS)

    Dexterous hand

    Valid

    2 (CLAW)

    Gripper

    Valid

    0 (NONE)

    Hand not connected

    HandState[] and HandTouchSensorData retain last valid values, not cleared

    0xFF (ERROR)

    Communication or firmware error

    Same as above

    • HandTouchSensorData ros2-msg @ hal/msg/HandTouchSensorData.msg

      # Palm touch sensor data (OmniHand: 5×5=25, only first 25 bytes used)
      uint8[36] palm_touch_data              # Palm touch data
      # Back-of-hand touch sensor data
      uint8[36] back_of_hand_touch_data      # Back-of-hand touch data
      
      # Fingertip touch sensor data (OmniHand: 16 sensors total, all 16 bytes used)
      uint8[16] thumb_touch_data             # Thumb fingertip
      uint8[16] index_finger_touch_data      # Index fingertip
      uint8[16] middle_finger_touch_data     # Middle fingertip
      uint8[16] ring_finger_touch_data       # Ring fingertip
      uint8[16] little_finger_touch_data     # Little fingertip
      

    Notes on HandState[] length and ordering:

    Hand Type

    Array Length

    Order

    Gripper OmniPicker

    1

    N/A

    Dexterous Hand OmniHand Dynamic Edition 2025

    10

    See joint index-to-name mapping

    • HandState ros2-msg @ hal/msg/HandState.msg

      # Hand status information
      string name                      # Joint name
      float64 position                 # Current position
      float64 velocity                 # Current velocity
      float64 effort                   # Current torque
      int32 state                      # State
      int32 faultcode                  # Fault code
      

      Note: The meaning and value range of these fields varies significantly depending on the hand type:

      • Gripper OmniPicker:

        name is set to "claw".

        Field Name

        Value Range

        Description

        position

        0.0-1.0

        Current travel; same value range as above

        velocity

        0.0-1.0

        Current speed; same value range as above

        effort

        0.0-1.0

        Current torque; same value range as above

        state

        0 - reached target position / 1 - gripper moving / 2 - gripper stalled / 3 - object dropped

        State

        faultcode

        0 - no fault / 1 - over-temperature warning / 2 - overspeed warning / 3 - initialization fault warning / 4 - limit-detection warning

        Fault code

      • Dexterous Hand OmniHand:

        Field Name

        Value Range

        Description

        position

        Current position (unit: rad)

        Current position

        velocity

        Raw value

        Current speed (to be adapted)

        effort

        Raw value

        Current torque (to be adapted)

        state

        N/A

        Not yet used

        faultcode

        Raw value

        Fault code

Hand Type Query Service

Service Name

Data Type

Description

/aimdk_5Fmsgs/srv/GetHandType

GetHandType

Actively query the hand type

  • GetHandType ros2-srv @ hal/srv/GetHandType.srv

    # Get hand type
    # Service: /aimdk_5Fmsgs/srv/GetHandType
    
    # Request
    CommonRequest request            # Common request
    
    ---
    
    # Response
    CommonResponse reponse           # Common response (not enabled; read the hand-type fields below directly)
    HandType left_hands_type         # Left hand type (left_hands_type.value: 1 (NIMBLE_HANDS dexterous hand), 2 (CLAW gripper))
    HandType right_hands_type        # Right hand type (right_hands_type.value: 1 (NIMBLE_HANDS dexterous hand), 2 (CLAW gripper))
    

Note

The reponse field of this service is not enabled. Read left_hands_type/right_hands_type directly, and do not rely on reponse.header.code/status to determine success or failure.

Programming Examples

For detailed programming examples and explanations, refer to:

Safety Notes

Warning

  • Autonomous control of the hand requires disabling native motor control. Ensure control of other joints and maintain proper safety precautions.

  • Do not modify hand component configurations manually. For special system-level adaptation, please contact technical support.

Caution

As standard ROS DO NOT handle cross-host service (request-response) well, please refer to SDK examples to use open interfaces in a robust way (with protection mechanisms e.g. exception safety and retransmission)

While the robot is in Stable Standing Mode or Locomotion Mode, DO NOT launch ROS nodes in rapid bulk (no more than 2 nodes per second is recommended), as a large number of nodes joining DDS discovery within a short period causes communication congestion and degrades motion control real-time performance, which may cause the robot to lose balance and fall