fix jogging stepping by holding one velocity instead of re-arming
`set_cartesian_velocity` passed `duration=velocity_command_ttl_s` on every message, so each one re-armed a timed segment and the controller re-planned the same motion. On a real Lite6 that is not smooth travel: the arm moves in steps. Reducing how often the velocity is sent does not help — re-arming four times a second still steps — so it now uses `duration=0`, the SDK's "always effective, will not stop automatically", and skips a velocity that has not changed. One command stands until a different one replaces it. That removes the controller-side expiry, which `_expire_jog` was relying on: it flipped `_jogging` and reported `ready` without commanding anything, because the controller's own timer had already stopped the arm. With the velocity held indefinitely that would leave an arm travelling while the node reported idle, so `_expire_jog` now queues the stop itself. It goes through the job queue rather than the driver, since it runs on the reporter thread and the control thread owns the driver. `VELOCITY_COMMAND_TTL_S` is unchanged in value and meaning to a caller, but it is now enforced here rather than by the controller. Both halves are one commit on purpose: `duration=0` without the stop in `_expire_jog` is an arm that never stops when its sender dies. Adds tests/test_driver.py — the driver had no direct coverage, because FakeArm replaces it everywhere else, which is why this was invisible to the suite.
This commit is contained in:
+9
-3
@@ -49,9 +49,15 @@ inputs:
|
||||
description: >-
|
||||
A continuous velocity command: a one-row struct {velocity} of 6 numbers
|
||||
[vx, vy, vz, wx, wy, wz] in mm/s and deg/s. A topic rather than a service
|
||||
because it expires on the controller's own TTL and a sender must keep
|
||||
sending; nothing is published in answer. It drives the arm, so the first
|
||||
non-zero one preempts a motion in play and robot_state turns to moving.
|
||||
because a sender keeps sending and nothing is published in answer. It
|
||||
drives the arm, so the first non-zero one preempts a motion in play and
|
||||
robot_state turns to moving.
|
||||
|
||||
The velocity is set on the controller once and held: an unchanged one is
|
||||
not sent to the arm again, because re-arming it makes the controller
|
||||
re-plan the same motion and the arm step rather than travel. A sender that
|
||||
goes quiet for longer than VELOCITY_COMMAND_TTL_S is stopped by this node,
|
||||
which is the deadman behind a sender that dies mid-jog.
|
||||
|
||||
outputs:
|
||||
response:
|
||||
|
||||
Reference in New Issue
Block a user