-
Notifications
You must be signed in to change notification settings - Fork 148
set_servo_angle_j() occasionally blocks for ~190ms in servo mode #154
Description
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_jcall returns0(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
-
Background thread does not prevent the stall — moving
set_servo_angle_jto 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. -
The stall duration is consistent — always ~190ms (±5ms), suggesting a fixed timeout or retry inside the SDK/controller.
-
Speed parameter matters — if
set_servo_angle_jinherits a slow speed (e.g., 0.35 rad/s from a priorset_servo_anglecall), the stall can escalate to a controller error (code 31, follow error) and the arm enters error state. Passingspeed=math.radians(180)prevents this escalation.