Skip to content

Fix reset_joints_within_limits_range clamping unselected joints - #8616

Merged
hujc7 merged 3 commits into
isaac-sim:mainfrom
Patrick-SCH03:fix/reset-joints-within-limits-range
Oct 31, 2026
Merged

hujc7 merged 3 commits into
isaac-sim:mainfrom
Patrick-SCH03:fix/reset-joints-within-limits-range

Conversation

@Patrick-SCH03

@Patrick-SCH03 Patrick-SCH03 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Description

reset_joints_within_limits_range samples values only for the joints listed in position_range / velocity_range and writes them into those columns, but then clamps the whole (num_envs, num_joints) tensor with the soft limits of the listed joints only:

joint_pos[:, self._pos_joint_ids] = math_utils.sample_uniform(...)
joint_pos_limits = self._asset.data.soft_joint_pos_limits.torch[0, self._pos_joint_ids]  # (num_selected, 2)
joint_pos = joint_pos.clamp(joint_pos_limits[:, 0], joint_pos_limits[:, 1])              # (num_envs, num_joints)

The velocity branch does the same. Depending on which joints are listed, this:

  • one joint listed: clamps every other joint to that joint's limits, so joints without a range do not keep their default state as the docstring says ("If the dictionary does not contain a key, the joint position or joint velocity is set to the default value for that joint.");
  • a subset of more than one joint: raises RuntimeError: The size of tensor a (4) must match the size of tensor b (2) at non-singleton dimension 1;
  • all joints, but keys not in joint order (e.g. {"j2|j3": ..., "j0|j1": ...}): applies each joint's limits to a different joint;
  • an empty position_range or velocity_range ({}): raises IndexError: tensors used as indices must be long, int, byte or bool tensors in __init__, because the ids are built with torch.tensor([]), which is a float tensor.

This clamps the samples with the limits of the sampled joints before writing them into those columns, and builds the id tensors with dtype=torch.int32. Listing every joint in joint order gives the same result as before.

No task config in the repository uses this term today, so only users of the public API are affected (the subset case currently fails with the RuntimeError above). I did not find an existing issue for this. Draft #8218 also edits this __call__ (moving it to env_mask) but keeps the whole-tensor clamp, so the two will need a small rebase whichever lands first.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Release backport

  • Backport this pull request to the active release branch after it merges into develop

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with uv run isaaclab --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have validated the changed behavior with focused coverage and applied the test-audit criteria to any test changes
  • I have added a changelog fragment under source/<pkg>/changelog.d/ for every touched package (do not edit CHANGELOG.rst or bump package versions — CI handles that)
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

Testing

  • Added a test in test/envs/mdp/test_events.py with an inline sim-free articulation double and four joints with distinct soft limits. Two cases: two joints listed out of joint order with a range wider than every soft limit in position_range and an empty velocity_range, then swapped. The listed joints must reach exactly their own soft limits, and every other joint position and velocity must keep its default. Both cases fail on develop and pass with the fix.
  • Mutation check: reverting either clamp line to clamp the whole tensor, taking the position or velocity limits in sorted instead of key order, dropping either dtype=torch.int32, or not writing the position or velocity samples each turns one case red.
  • test_root_state_events.py and test_terminations.py still pass (CPU, 6 passed together with the new test).
  • Ruff v0.14.10 (the pre-commit pin) check and format and codespell are clean on the changed files, and I checked the changelog fragment name and format against the rules in tools/changelog/cli.py. I ran these directly because the full uv run isaaclab --format environment isn't available on my Windows machine.

The sampled joint positions and velocities were written only to the
joints listed in position_range and velocity_range, but the clamp to
those joints' soft limits was applied to the whole joint tensor. Joints
without a range were moved to the limits of the listed joints, a subset
of more than one joint raised a shape mismatch, and joints listed out of
order were clamped with the wrong limits. Clamp the samples to the
limits of the sampled joints before writing them instead.

Build the joint id tensors as integer tensors so that an empty range
dictionary no longer raises an IndexError.

Signed-off-by: Patrick-SCH03 <wwoo5241@gmail.com>
@Patrick-SCH03
Patrick-SCH03 requested a review from a team October 15, 2026 19:03
@github-actions github-actions Bot added bug Something isn't working isaac-lab Related to Isaac Lab team labels Oct 15, 2026
@greptile-apps

greptile-apps Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge.

Summary

The PR fixes reset_joints_within_limits_range by clamping sampled values before writing them to selected joints.

  • Joint resets clamp only the joints named in each range.

No actionable issues were found. Review checks were static; tests were not run.

Reviews (1) · Last reviewed commit: "Fix reset_joints_within_limits_range cla..." · Reviewed by Greptile

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isaac Lab Review Bot

All reviewed code categories look good.

  • PR description: The title and body match the clamp, index-dtype, changelog, and test changes; reported validation is relevant, and no performance evidence is required for this focused reset-path correction.
  • Design and architecture: Architecture looks good.
  • Scope and over-engineering: No over-engineering issues.
  • API: API changes look good.
  • Compatibility and deprecation: No breaking changes identified.
  • Implementation: Implementation looks good.
  • Style consistency: Style consistency looks good.
  • Test quality: Test quality looks good.

No blocking issues. No inline findings.

Automated review; human maintainers own approval decisions.

@AntoineRichard AntoineRichard left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @Patrick-SCH03!


# store the joint pos ids (used later to sample the joint positions)
self._pos_joint_ids = torch.tensor(pos_joint_ids, device=self._pos_ranges.device)
self._pos_joint_ids = torch.tensor(pos_joint_ids, dtype=torch.long, device=self._pos_ranges.device)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use int32


# store the joint vel ids (used later to sample the joint positions)
self._vel_joint_ids = torch.tensor(vel_joint_ids, device=self._vel_ranges.device)
self._vel_joint_ids = torch.tensor(vel_joint_ids, dtype=torch.long, device=self._vel_ranges.device)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use int32

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be a lot smaller. The one-joint, subset and out-of-order cases all fail because of the same clamp line, and the empty pos and empty vel cases mirror each other. Two cases cover every fixed line: listed keys out of joint order with ranges wider than the soft limits, with an empty dict on the other side, then swapped. Those two fail on every single-line revert of the fix that the current five catch, and they also catch velocity limits applied in the wrong joint order. Inlining the env double removes _make_env. Could you also move it to source/isaaclab/test/envs/mdp/test_events.py, next to test_actions.py and test_terminations.py?

Signed-off-by: Patrick-SCH03 <wwoo5241@gmail.com>
@Patrick-SCH03

Copy link
Copy Markdown
Contributor Author

Thanks @AntoineRichard! Done in 2fcab12:

  • Both joint id tensors are now int32.
  • The test is now two cases in source/isaaclab/test/envs/mdp/test_events.py, with the env double inlined: two joints listed out of joint order with a range wider than the soft limits on one side and an empty dict on the other, then swapped. The old file is removed.

I checked the two cases against single-line reverts of the fix: each clamp line, each dtype, and position or velocity limits taken in joint order instead of key order all fail one case, and both fail on develop. I also made the test check that the listed joints reach exactly their own limits, so a regression that stops writing the samples is caught too. The PR description is updated to match.

@Patrick-SCH03

Copy link
Copy Markdown
Contributor Author

@AntoineRichard friendly ping: both requests are addressed in 2fcab12 (int32 joint ids, and the test is down to two cases in test/envs/mdp/test_events.py). Could you take another look when you have a moment? Thanks!

@AntoineRichard AntoineRichard left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fixes!

@AntoineRichard

Copy link
Copy Markdown
Collaborator

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Oct 27, 2026
@AntoineRichard

Copy link
Copy Markdown
Collaborator

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Oct 27, 2026
@maxkra15
maxkra15 self-requested a review October 28, 2026 12:37
@AntoineRichard

Copy link
Copy Markdown
Collaborator

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Oct 30, 2026
@hujc7
hujc7 merged commit 6bb6548 into isaac-sim:main Oct 31, 2026
133 of 158 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working isaac-lab Related to Isaac Lab team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants