Skip to content

fix(robot): index actuator qpos reads with jnt_qposadr, not jnt_dofadr#171

Merged
vikashplus merged 1 commit into
vikashplus:devfrom
XnetLoL:ouassim/fix-actuator-qposadr
Jul 15, 2026
Merged

fix(robot): index actuator qpos reads with jnt_qposadr, not jnt_dofadr#171
vikashplus merged 1 commit into
vikashplus:devfrom
XnetLoL:ouassim/fix-actuator-qposadr

Conversation

@XnetLoL

@XnetLoL XnetLoL commented Jul 14, 2026

Copy link
Copy Markdown

Bug

Robot._resolve_data_ids caches each joint actuator's feedback address (data_id) into sim.data.qpos, but computes it with jnt_dofadr — the qvel address space. The two address spaces coincide only while every preceding joint is 1-DOF: any free/ball joint earlier in the model shifts every subsequent actuator's qpos read by the qpos/qvel size difference (freejoint: 7 qpos vs 6 dofs).

The stale read feeds the velocity limiter in process_actuator(), which re-anchors each command to the wrong joint's position — in practice the arm freezes at whatever pose keeps the misread error small, silently ignoring position targets.

Repro

Observed on anthrohive URDtriosPickPlace-v0, where a manipulable box (freejoint) is defined before the UR5e: the arm ignored all position targets until this fix. Any model that places a freejoint body ahead of the actuated kinematic chain hits the same shift.

Fix

One-line change: use jnt_qposadr[actuator_trnid] for the qpos data_id. Models with only 1-DOF joints (or with the robot defined first) are byte-for-byte unaffected, since the two tables agree there.

Note: this is independent of the fix_act_id_indexing branch (act_id vs sim_id remapping in normalize_actions) — different bug, no overlapping lines.

Robot._resolve_data_ids caches each joint actuator's feedback address as
data_id into sim.data.qpos, but computed it with jnt_dofadr (the qvel
address).  qpos and qvel addresses coincide only while all preceding
joints are 1-DOF: any free/ball joint earlier in the model (e.g. a
manipulable object defined before the arm) shifts every subsequent
actuator's read by the qpos/qvel size difference (freejoint: 7 vs 6).

The stale read feeds the velocity limiter in process_actuator(), which
re-anchors each command to the wrong joint's position — in practice the
arm freezes at whatever pose keeps the misread error small.

Observed on anthrohive URDtriosPickPlace-v0 (box freejoint precedes the
UR5e): the arm ignored all position targets until this fix.
@vikashplus
vikashplus merged commit c3fe70b into vikashplus:dev Jul 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants