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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions