Unverified Commit cb9fee62 authored by Kelly Guo's avatar Kelly Guo Committed by GitHub

Fixes default joint pos when setting joint limits (#1040)

# Description

When setting joint limits, the existing default joint positions can fall
outside of the bounds of the new joint limits. This change clips the
default joint positions to ensure they are within the bounds of the new
limits.

## Type of change

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


## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [ ] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
parent 73c47e4f
[package]
# Note: Semantic Versioning is used: https://semver.org/
version = "0.25.0"
version = "0.25.1"
# Description
title = "Isaac Lab framework for Robot Learning"
......
Changelog
---------
0.25.1 (2024-10-10)
~~~~~~~~~~~~~~~~~~~
Fixed
^^^^^
* Fixed potential issue where default joint positions can fall outside of the limits being set with Articulation's
``write_joint_limits_to_sim`` API.
0.25.0 (2024-10-06)
~~~~~~~~~~~~~~~~~~~
......@@ -14,7 +24,7 @@ Added
0.24.20 (2024-10-07)
~~~~~~~~~~~~~~~~~~~~
Fixes
Fixed
^^^^^
* Fixed the :meth:`omni.isaac.lab.envs.mdp.events.randomize_rigid_body_material` function to
......
......@@ -539,6 +539,13 @@ class Articulation(AssetBase):
env_ids = env_ids[:, None]
# set into internal buffers
self._data.joint_limits[env_ids, joint_ids] = limits
# update default joint pos to stay within the new limits
if torch.any((self._data.default_joint_pos < limits[..., 0]) | (self._data.default_joint_pos > limits[..., 1])):
self._data.default_joint_pos = torch.clamp(self._data.default_joint_pos, limits[..., 0], limits[..., 1])
carb.log_warn(
"Some default joint positions are outside of the range of the new joint limits. Default joint positions"
" will be clamped to be within the new joint limits."
)
# set into simulation
self.root_physx_view.set_dof_limits(self._data.joint_limits.cpu(), indices=physx_env_ids.cpu())
......
......@@ -542,6 +542,48 @@ class TestArticulation(unittest.TestCase):
# Check if articulation is initialized
self.assertFalse(articulation._is_initialized)
def test_joint_limits(self):
"""Test write_joint_limits_to_sim API and when default pos falls outside of the new limits."""
for num_articulations in (1, 2):
for device in ("cuda:0", "cpu"):
with self.subTest(num_articulations=num_articulations, device=device):
with build_simulation_context(device=device, add_ground_plane=True, auto_add_lighting=True) as sim:
# Create articulation
articulation_cfg = generate_articulation_cfg(articulation_type="panda")
articulation, _ = generate_articulation(articulation_cfg, num_articulations, device)
# Play sim
sim.reset()
# Check if articulation is initialized
self.assertTrue(articulation._is_initialized)
# Get current default joint pos
default_joint_pos = articulation._data.default_joint_pos.clone()
# Set new joint limits
limits = torch.zeros(num_articulations, articulation.num_joints, 2, device=device)
limits[..., 0] = (
torch.rand(num_articulations, articulation.num_joints, device=device) + 5.0
) * -1.0
limits[..., 1] = torch.rand(num_articulations, articulation.num_joints, device=device) + 5.0
articulation.write_joint_limits_to_sim(limits)
# Check new limits are in place
torch.testing.assert_close(articulation._data.joint_limits, limits)
torch.testing.assert_close(articulation._data.default_joint_pos, default_joint_pos)
# Set new joint limits that invalidate default joint pos
limits = torch.zeros(num_articulations, articulation.num_joints, 2, device=device)
limits[..., 0] = torch.rand(num_articulations, articulation.num_joints, device=device) * -0.1
limits[..., 1] = torch.rand(num_articulations, articulation.num_joints, device=device) * 0.1
articulation.write_joint_limits_to_sim(limits)
# Check if all values are within the bounds
within_bounds = (articulation._data.default_joint_pos >= limits[..., 0]) & (
articulation._data.default_joint_pos <= limits[..., 1]
)
self.assertTrue(torch.all(within_bounds))
def test_external_force_on_single_body(self):
"""Test application of external force on the base of the articulation."""
for num_articulations in (1, 2):
......
......@@ -8,6 +8,7 @@
Any tests not listed here will use the default timeout.
"""
PER_TEST_TIMEOUTS = {
"test_articulation.py": 200,
"test_environments.py": 1200, # This test runs through all the environments for 100 steps each
"test_environment_determinism.py": 200, # This test runs through many the environments for 100 steps each
"test_env_rendering_logic.py": 300,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment