Unverified Commit 87130f23 authored by Ossama Ahmed's avatar Ossama Ahmed Committed by GitHub

Updates Joint Friction Parameters to Isaac Sim 5.0 PhysX APIs (#557)

# Description

Updated Joint Friction Parameters to Isaac Sim 5.0/ PhysX APIs and
exposed joint's viscous_frictions and dynamic_frictions.


## Checklist

- [X] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.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 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 2084935e
...@@ -86,7 +86,13 @@ class ActuatorBase(ABC): ...@@ -86,7 +86,13 @@ class ActuatorBase(ABC):
"""The armature of the actuator joints. Shape is (num_envs, num_joints).""" """The armature of the actuator joints. Shape is (num_envs, num_joints)."""
friction: torch.Tensor friction: torch.Tensor
"""The joint friction of the actuator joints. Shape is (num_envs, num_joints).""" """The joint static friction of the actuator joints. Shape is (num_envs, num_joints)."""
dynamic_friction: torch.Tensor
"""The joint dynamic friction of the actuator joints. Shape is (num_envs, num_joints)."""
viscous_friction: torch.Tensor
"""The joint viscous friction of the actuator joints. Shape is (num_envs, num_joints)."""
_DEFAULT_MAX_EFFORT_SIM: ClassVar[float] = 1.0e9 _DEFAULT_MAX_EFFORT_SIM: ClassVar[float] = 1.0e9
"""The default maximum effort for the actuator joints in the simulation. Defaults to 1.0e9. """The default maximum effort for the actuator joints in the simulation. Defaults to 1.0e9.
...@@ -106,6 +112,8 @@ class ActuatorBase(ABC): ...@@ -106,6 +112,8 @@ class ActuatorBase(ABC):
damping: torch.Tensor | float = 0.0, damping: torch.Tensor | float = 0.0,
armature: torch.Tensor | float = 0.0, armature: torch.Tensor | float = 0.0,
friction: torch.Tensor | float = 0.0, friction: torch.Tensor | float = 0.0,
dynamic_friction: torch.Tensor | float = 0.0,
viscous_friction: torch.Tensor | float = 0.0,
effort_limit: torch.Tensor | float = torch.inf, effort_limit: torch.Tensor | float = torch.inf,
velocity_limit: torch.Tensor | float = torch.inf, velocity_limit: torch.Tensor | float = torch.inf,
): ):
...@@ -131,7 +139,11 @@ class ActuatorBase(ABC): ...@@ -131,7 +139,11 @@ class ActuatorBase(ABC):
If a tensor, then the shape is (num_envs, num_joints). If a tensor, then the shape is (num_envs, num_joints).
armature: The default joint armature. Defaults to 0.0. armature: The default joint armature. Defaults to 0.0.
If a tensor, then the shape is (num_envs, num_joints). If a tensor, then the shape is (num_envs, num_joints).
friction: The default joint friction. Defaults to 0.0. friction: The default joint static friction. Defaults to 0.0.
If a tensor, then the shape is (num_envs, num_joints).
dynamic_friction: The default joint dynamic friction. Defaults to 0.0.
If a tensor, then the shape is (num_envs, num_joints).
viscous_friction: The default joint viscous friction. Defaults to 0.0.
If a tensor, then the shape is (num_envs, num_joints). If a tensor, then the shape is (num_envs, num_joints).
effort_limit: The default effort limit. Defaults to infinity. effort_limit: The default effort limit. Defaults to infinity.
If a tensor, then the shape is (num_envs, num_joints). If a tensor, then the shape is (num_envs, num_joints).
...@@ -156,6 +168,8 @@ class ActuatorBase(ABC): ...@@ -156,6 +168,8 @@ class ActuatorBase(ABC):
# parse joint armature and friction # parse joint armature and friction
self.armature = self._parse_joint_parameter(self.cfg.armature, armature) self.armature = self._parse_joint_parameter(self.cfg.armature, armature)
self.friction = self._parse_joint_parameter(self.cfg.friction, friction) self.friction = self._parse_joint_parameter(self.cfg.friction, friction)
self.dynamic_friction = self._parse_joint_parameter(self.cfg.dynamic_friction, dynamic_friction)
self.viscous_friction = self._parse_joint_parameter(self.cfg.viscous_friction, viscous_friction)
# parse joint limits # parse joint limits
# -- velocity # -- velocity
self.velocity_limit_sim = self._parse_joint_parameter(self.cfg.velocity_limit_sim, velocity_limit) self.velocity_limit_sim = self._parse_joint_parameter(self.cfg.velocity_limit_sim, velocity_limit)
......
...@@ -141,18 +141,26 @@ class ActuatorBaseCfg: ...@@ -141,18 +141,26 @@ class ActuatorBaseCfg:
""" """
friction: dict[str, float] | float | None = None friction: dict[str, float] | float | None = None
r"""The friction coefficient of the joints in the group. Defaults to None. r"""The static friction coefficient of the joints in the group. Defaults to None.
The joint friction is a unitless quantity. It relates the magnitude of the spatial force transmitted The joint static friction is a unitless quantity. It relates the magnitude of the spatial force transmitted
from the parent body to the child body to the maximal friction force that may be applied by the solver from the parent body to the child body to the maximal static friction force that may be applied by the solver
to resist the joint motion. to resist the joint motion.
Mathematically, this means that: :math:`F_{resist} \leq \mu F_{spatial}`, where :math:`F_{resist}` Mathematically, this means that: :math:`F_{resist} \leq \mu F_{spatial}`, where :math:`F_{resist}`
is the resisting force applied by the solver and :math:`F_{spatial}` is the spatial force is the resisting force applied by the solver and :math:`F_{spatial}` is the spatial force
transmitted from the parent body to the child body. The simulated friction effect is therefore transmitted from the parent body to the child body. The simulated static friction effect is therefore
similar to static and Coulomb friction. similar to static and Coulomb static friction.
If None, the joint friction is set to the value from the USD joint prim. If None, the joint static friction is set to the value from the USD joint prim.
"""
dynamic_friction: dict[str, float] | float | None = None
"""The dynamic friction coefficient of the joints in the group. Defaults to None.
"""
viscous_friction: dict[str, float] | float | None = None
"""The viscous friction coefficient of the joints in the group. Defaults to None.
""" """
......
...@@ -379,6 +379,8 @@ class RemotizedPDActuator(DelayedPDActuator): ...@@ -379,6 +379,8 @@ class RemotizedPDActuator(DelayedPDActuator):
damping: torch.Tensor | float = 0.0, damping: torch.Tensor | float = 0.0,
armature: torch.Tensor | float = 0.0, armature: torch.Tensor | float = 0.0,
friction: torch.Tensor | float = 0.0, friction: torch.Tensor | float = 0.0,
dynamic_friction: torch.Tensor | float = 0.0,
viscous_friction: torch.Tensor | float = 0.0,
effort_limit: torch.Tensor | float = torch.inf, effort_limit: torch.Tensor | float = torch.inf,
velocity_limit: torch.Tensor | float = torch.inf, velocity_limit: torch.Tensor | float = torch.inf,
): ):
...@@ -387,7 +389,19 @@ class RemotizedPDActuator(DelayedPDActuator): ...@@ -387,7 +389,19 @@ class RemotizedPDActuator(DelayedPDActuator):
cfg.velocity_limit = torch.inf cfg.velocity_limit = torch.inf
# call the base method and set default effort_limit and velocity_limit to inf # call the base method and set default effort_limit and velocity_limit to inf
super().__init__( super().__init__(
cfg, joint_names, joint_ids, num_envs, device, stiffness, damping, armature, friction, torch.inf, torch.inf cfg,
joint_names,
joint_ids,
num_envs,
device,
stiffness,
damping,
armature,
friction,
dynamic_friction,
viscous_friction,
effort_limit,
velocity_limit,
) )
self._joint_parameter_lookup = torch.tensor(cfg.joint_parameter_lookup, device=device) self._joint_parameter_lookup = torch.tensor(cfg.joint_parameter_lookup, device=device)
# define remotized joint torque limit # define remotized joint torque limit
......
...@@ -190,13 +190,29 @@ class ArticulationData: ...@@ -190,13 +190,29 @@ class ArticulationData:
""" """
default_joint_friction_coeff: torch.Tensor = None default_joint_friction_coeff: torch.Tensor = None
"""Default joint friction coefficient of all joints. Shape is (num_instances, num_joints). """Default joint static friction coefficient of all joints. Shape is (num_instances, num_joints).
This quantity is configured through the actuator model's :attr:`isaaclab.actuators.ActuatorBaseCfg.friction` This quantity is configured through the actuator model's :attr:`isaaclab.actuators.ActuatorBaseCfg.friction`
parameter. If the parameter's value is None, the value parsed from the USD schema, at the time of initialization, parameter. If the parameter's value is None, the value parsed from the USD schema, at the time of initialization,
is used. is used.
""" """
default_joint_dynamic_friction_coeff: torch.Tensor = None
"""Default joint dynamic friction coefficient of all joints. Shape is (num_instances, num_joints).
This quantity is configured through the actuator model's :attr:`isaaclab.actuators.ActuatorBaseCfg.dynamic_friction`
parameter. If the parameter's value is None, the value parsed from the USD schema, at the time of initialization,
is used.
"""
default_joint_viscous_friction_coeff: torch.Tensor = None
"""Default joint viscous friction coefficient of all joints. Shape is (num_instances, num_joints).
This quantity is configured through the actuator model's :attr:`isaaclab.actuators.ActuatorBaseCfg.viscous_friction`
parameter. If the parameter's value is None, the value parsed from the USD schema, at the time of initialization,
is used.
"""
default_joint_pos_limits: torch.Tensor = None default_joint_pos_limits: torch.Tensor = None
"""Default joint position limits of all joints. Shape is (num_instances, num_joints, 2). """Default joint position limits of all joints. Shape is (num_instances, num_joints, 2).
...@@ -330,7 +346,13 @@ class ArticulationData: ...@@ -330,7 +346,13 @@ class ArticulationData:
"""Joint armature provided to the simulation. Shape is (num_instances, num_joints).""" """Joint armature provided to the simulation. Shape is (num_instances, num_joints)."""
joint_friction_coeff: torch.Tensor = None joint_friction_coeff: torch.Tensor = None
"""Joint friction coefficient provided to the simulation. Shape is (num_instances, num_joints).""" """Joint static friction coefficient provided to the simulation. Shape is (num_instances, num_joints)."""
joint_dynamic_friction_coeff: torch.Tensor = None
"""Joint dynamic friction coefficient provided to the simulation. Shape is (num_instances, num_joints)."""
joint_viscous_friction_coeff: torch.Tensor = None
"""Joint viscous friction coefficient provided to the simulation. Shape is (num_instances, num_joints)."""
joint_pos_limits: torch.Tensor = None joint_pos_limits: torch.Tensor = None
"""Joint position limits provided to the simulation. Shape is (num_instances, num_joints, 2). """Joint position limits provided to the simulation. Shape is (num_instances, num_joints, 2).
......
...@@ -1899,5 +1899,44 @@ def test_spatial_tendons(sim, num_articulations, device): ...@@ -1899,5 +1899,44 @@ def test_spatial_tendons(sim, num_articulations, device):
articulation.update(sim.cfg.dt) articulation.update(sim.cfg.dt)
@pytest.mark.parametrize("add_ground_plane", [True])
@pytest.mark.parametrize("num_articulations", [1, 2])
@pytest.mark.parametrize("device", ["cuda:0", "cpu"])
def test_write_joint_frictions_to_sim(sim, num_articulations, device, add_ground_plane):
"""Test applying of joint position target functions correctly for a robotic arm."""
articulation_cfg = generate_articulation_cfg(articulation_type="panda")
articulation, _ = generate_articulation(
articulation_cfg=articulation_cfg, num_articulations=num_articulations, device=device
)
# Play the simulator
sim.reset()
for _ in range(100):
# perform step
sim.step()
# update buffers
articulation.update(sim.cfg.dt)
# apply action to the articulation
dynamic_friction = torch.rand(num_articulations, articulation.num_joints, device=device)
viscous_friction = torch.rand(num_articulations, articulation.num_joints, device=device)
friction = torch.rand(num_articulations, articulation.num_joints, device=device)
articulation.write_joint_dynamic_friction_coefficient_to_sim(dynamic_friction)
articulation.write_joint_viscous_friction_coefficient_to_sim(viscous_friction)
articulation.write_joint_friction_coefficient_to_sim(friction)
articulation.write_data_to_sim()
for _ in range(100):
# perform step
sim.step()
# update buffers
articulation.update(sim.cfg.dt)
assert torch.allclose(articulation.data.joint_dynamic_friction_coeff, dynamic_friction)
assert torch.allclose(articulation.data.joint_viscous_friction_coeff, viscous_friction)
assert torch.allclose(articulation.data.joint_friction_coeff, friction)
if __name__ == "__main__": if __name__ == "__main__":
pytest.main([__file__, "-v", "--maxfail=1"]) pytest.main([__file__, "-v", "--maxfail=1"])
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