Unverified Commit e4d1cdd3 authored by Mayank Mittal's avatar Mayank Mittal Committed by GitHub

Fixes unwanted squeeze in Articulation class for 1-joint assets (#397)

# Description

This MR fixes the issue with printing articulation joint information
with the `Articulation` class. When the number of joints are 1, the
`squeeze(0).tolist()` operation makes the tensor a float item instead of
a list.

This MR removes the squeeze operation and adds a unit test to check that
single-joint articulations work.

Fixes https://github.com/NVIDIA-Omniverse/orbit/issues/238

## 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
`./orbit.sh --format`
- [x] 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 run all the tests with `./orbit.sh --test` and they pass
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
parent 1e708cbd
[package] [package]
# Note: Semantic Versioning is used: https://semver.org/ # Note: Semantic Versioning is used: https://semver.org/
version = "0.10.20" version = "0.10.21"
# Description # Description
title = "ORBIT framework for Robot Learning" title = "ORBIT framework for Robot Learning"
......
Changelog Changelog
--------- ---------
0.10.21 (2024-02-12)
~~~~~~~~~~~~~~~~~~~~
Fixed
^^^^^
* Fixed the printing of articulation joint information when the articulation has only one joint.
Earlier, the function was performing a squeeze operation on the tensor, which caused an error when
trying to index the tensor of shape (1,).
0.10.20 (2024-02-12) 0.10.20 (2024-02-12)
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
......
...@@ -703,15 +703,15 @@ class Articulation(RigidObject): ...@@ -703,15 +703,15 @@ class Articulation(RigidObject):
"""Log information about the articulation's simulated joints.""" """Log information about the articulation's simulated joints."""
# read out all joint parameters from simulation # read out all joint parameters from simulation
# -- gains # -- gains
stiffnesses = self.root_physx_view.get_dof_stiffnesses()[0].squeeze(0).tolist() stiffnesses = self.root_physx_view.get_dof_stiffnesses()[0].tolist()
dampings = self.root_physx_view.get_dof_dampings()[0].squeeze(0).tolist() dampings = self.root_physx_view.get_dof_dampings()[0].tolist()
# -- properties # -- properties
armatures = self.root_physx_view.get_dof_armatures()[0].squeeze(0).tolist() armatures = self.root_physx_view.get_dof_armatures()[0].tolist()
frictions = self.root_physx_view.get_dof_friction_coefficients()[0].squeeze(0).tolist() frictions = self.root_physx_view.get_dof_friction_coefficients()[0].tolist()
# -- limits # -- limits
position_limits = self.root_physx_view.get_dof_limits()[0].squeeze(0).tolist() position_limits = self.root_physx_view.get_dof_limits()[0].tolist()
velocity_limits = self.root_physx_view.get_dof_max_velocities()[0].squeeze(0).tolist() velocity_limits = self.root_physx_view.get_dof_max_velocities()[0].tolist()
effort_limits = self.root_physx_view.get_dof_max_forces()[0].squeeze(0).tolist() effort_limits = self.root_physx_view.get_dof_max_forces()[0].tolist()
# create table for term information # create table for term information
table = PrettyTable(float_format=".3f") table = PrettyTable(float_format=".3f")
table.title = f"Simulation Joint Information (Prim path: {self.cfg.prim_path})" table.title = f"Simulation Joint Information (Prim path: {self.cfg.prim_path})"
......
...@@ -147,6 +147,44 @@ class TestArticulation(unittest.TestCase): ...@@ -147,6 +147,44 @@ class TestArticulation(unittest.TestCase):
# update robot # update robot
robot.update(self.dt) robot.update(self.dt)
def test_initialization_fixed_base_single_joint(self):
"""Test initialization for fixed base articulation with a single joint."""
# Create articulation
robot_cfg = ArticulationCfg(
spawn=sim_utils.UsdFileCfg(usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/Simple/revolute_articulation.usd"),
actuators={
"joint": ImplicitActuatorCfg(
joint_names_expr=[".*"],
effort_limit=400.0,
velocity_limit=100.0,
stiffness=0.0,
damping=10.0,
),
},
)
robot = Articulation(cfg=robot_cfg.replace(prim_path="/World/Robot"))
# Check that boundedness of articulation is correct
self.assertEqual(ctypes.c_long.from_address(id(robot)).value, 1)
# Play sim
self.sim.reset()
# Check if robot is initialized
self.assertTrue(robot._is_initialized)
# Check that fixed base
self.assertTrue(robot.is_fixed_base)
# Check buffers that exists and have correct shapes
self.assertTrue(robot.data.root_pos_w.shape == (1, 3))
self.assertTrue(robot.data.root_quat_w.shape == (1, 4))
self.assertTrue(robot.data.joint_pos.shape == (1, 1))
# Simulate physics
for _ in range(10):
# perform rendering
self.sim.step()
# update robot
robot.update(self.dt)
def test_external_force_on_single_body(self): def test_external_force_on_single_body(self):
"""Test application of external force on the base of the robot.""" """Test application of external force on the base of the robot."""
......
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