Skip to content

set_servo_angle_j() occasionally blocks for ~190ms in servo mode #154

@hanyangclarence

Description

@hanyangclarence

Environment

  • xArm SDK: v1.17.3
  • Robot: xArm7, firmware v2.7.1 (XS1305/AC1304)
  • Connection: TCP over local network (192.168.1.x)
  • OS: Ubuntu (WSL2), Python 3.10+

Description

When streaming joint commands via set_servo_angle_j() in servo mode (mode 1) at 60-100Hz, the call occasionally blocks for ~190ms instead of the normal ~1-3ms. This causes the arm to physically stall at its current position for that duration, then resume. It happens roughly once per 10-second run.

Reproduction

Minimal script that reproduces the issue:

from xarm.wrapper import XArmAPI
import math, time

arm = XArmAPI("192.168.1.208")
arm.motion_enable(enable=True)
arm.set_mode(0)
arm.set_state(0)

# Move to a starting pose
start_angles = [-0.54, 0.29, -0.40, 0.48, 2.19, 1.65, -1.44]
arm.set_servo_angle(angle=start_angles, speed=0.35, is_radian=True, wait=True)

# Switch to servo mode
arm.set_joint_maxacc(20.0, is_radian=True)
arm.set_joint_jerk(100.0, is_radian=True)
arm.set_mode(1)
arm.set_state(0)

code, states = arm.get_joint_states(is_radian=True, num=3)
baseline = list(states[0])

# Stream a sine wave on joint 0 at 100Hz
servo_speed = math.radians(180)
dt = 0.01  # 100Hz
t0 = time.monotonic()

for _ in range(1000):  # 10 seconds
    t = time.monotonic() - t0
    target = list(baseline)
    target[0] = baseline[0] + 0.3 * math.sin(2 * math.pi * 0.5 * t)

    t_cmd = time.monotonic()
    arm.set_servo_angle_j(target, speed=servo_speed, is_radian=True)
    cmd_ms = (time.monotonic() - t_cmd) * 1000

    if cmd_ms > 50:
        print(f"SLOW: {cmd_ms:.0f}ms at t={t:.3f}s")

    elapsed = time.monotonic() - (t0 + _ * dt)
    if elapsed < dt:
        time.sleep(dt - elapsed)

arm.disconnect()

Observed behavior

Typical output:

[SDK][WARNING][...][base.py:2067] - The mode may be incorrect, just as a reminder, mode: 1 (0)
[SDK][WARNING][...][base.py:2067] - The mode may be incorrect, just as a reminder, mode: 1 (0)
(... ~10 warnings at startup ...)
SLOW: 192ms at t=6.867s
  • The set_servo_angle_j call returns 0 (success) but takes ~190ms
  • The arm physically freezes for that duration, then resumes
  • Happens more frequently with large amplitude motions on base joints (joint 0, 1)
  • The SDK warnings ("The mode may be incorrect") always appear at the start, even on clean runs

Additional observations

  1. Background thread does not prevent the stall — moving set_servo_angle_j to a dedicated 100Hz background thread (same pattern as the xArm device driver) isolates the recording loop but the arm still physically stalls for ~190ms when the call blocks.

  2. The stall duration is consistent — always ~190ms (±5ms), suggesting a fixed timeout or retry inside the SDK/controller.

  3. Speed parameter matters — if set_servo_angle_j inherits a slow speed (e.g., 0.35 rad/s from a prior set_servo_angle call), the stall can escalate to a controller error (code 31, follow error) and the arm enters error state. Passing speed=math.radians(180) prevents this escalation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions