Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions source/isaaclab/changelog.d/passive-tendons.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Added
^^^^^
* Updates tendon randomization events to support newton tendons
* Adds support to modify MJC usd schema
133 changes: 73 additions & 60 deletions source/isaaclab/isaaclab/envs/mdp/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,8 @@ def __call__(
operation: Literal["add", "scale", "abs"] = "abs",
distribution: Literal["uniform", "log_uniform", "gaussian"] = "uniform",
):
_backend = env.sim.physics_manager.__name__.lower()

# resolve environment ids
if env_ids is None:
env_ids = torch.arange(env.scene.num_envs, device=self.asset.device)
Expand Down Expand Up @@ -1528,80 +1530,91 @@ def __call__(

# limit stiffness
if limit_stiffness_distribution_params is not None:
limit_stiffness = _randomize_prop_by_op(
self.asset.data.fixed_tendon_limit_stiffness.torch.clone(),
limit_stiffness_distribution_params,
env_ids,
tendon_ids,
operation=operation,
distribution=distribution,
)
self.asset.set_fixed_tendon_limit_stiffness(
limit_stiffness[env_ids[:, None], tendon_ids], tendon_ids, env_ids
)
if _backend == "physx":
limit_stiffness = _randomize_prop_by_op(
self.asset.data.fixed_tendon_limit_stiffness.torch.clone(),
limit_stiffness_distribution_params,
env_ids,
tendon_ids,
operation=operation,
distribution=distribution,
)
self.asset.set_fixed_tendon_limit_stiffness(
limit_stiffness[env_ids[:, None], tendon_ids], tendon_ids, env_ids
)
else:
raise NotImplementedError("Limit stiffness is not support in Newton.")

# position limits
if lower_limit_distribution_params is not None or upper_limit_distribution_params is not None:
limit = self.asset.data.fixed_tendon_pos_limits.torch.clone()
# -- lower limit
if lower_limit_distribution_params is not None:
limit[..., 0] = _randomize_prop_by_op(
limit[..., 0],
lower_limit_distribution_params,
if _backend == "physx":
limit = self.asset.data.fixed_tendon_pos_limits.torch.clone()
# -- lower limit
if lower_limit_distribution_params is not None:
limit[..., 0] = _randomize_prop_by_op(
limit[..., 0],
lower_limit_distribution_params,
env_ids,
tendon_ids,
operation=operation,
distribution=distribution,
)
# -- upper limit
if upper_limit_distribution_params is not None:
limit[..., 1] = _randomize_prop_by_op(
limit[..., 1],
upper_limit_distribution_params,
env_ids,
tendon_ids,
operation=operation,
distribution=distribution,
)

# check if the limits are valid
tendon_limits = limit[env_ids[:, None], tendon_ids]
if (tendon_limits[..., 0] > tendon_limits[..., 1]).any():
raise ValueError(
"Randomization term 'randomize_fixed_tendon_parameters' is setting lower tendon limits that are"
" greater than upper tendon limits."
)
self.asset.set_fixed_tendon_position_limit_index(
limit=tendon_limits, fixed_tendon_ids=tendon_ids, env_ids=env_ids
)
else:
raise NotImplementedError("Position limits is not yet implemented with Newton.")

# rest length
if rest_length_distribution_params is not None:
if _backend == "physx":
rest_length = _randomize_prop_by_op(
self.asset.data.fixed_tendon_rest_length.torch.clone(),
rest_length_distribution_params,
env_ids,
tendon_ids,
operation=operation,
distribution=distribution,
)
# -- upper limit
if upper_limit_distribution_params is not None:
limit[..., 1] = _randomize_prop_by_op(
limit[..., 1],
upper_limit_distribution_params,
self.asset.set_fixed_tendon_rest_length_index(
rest_length=rest_length[env_ids[:, None], tendon_ids], fixed_tendon_ids=tendon_ids, env_ids=env_ids
)
else:
raise NotImplementedError("Rest length is not yet implemented with Newton.")
# offset
if offset_distribution_params is not None:
if _backend == "physx":
offset = _randomize_prop_by_op(
self.asset.data.fixed_tendon_offset.torch.clone(),
offset_distribution_params,
env_ids,
tendon_ids,
operation=operation,
distribution=distribution,
)

# check if the limits are valid
tendon_limits = limit[env_ids[:, None], tendon_ids]
if (tendon_limits[..., 0] > tendon_limits[..., 1]).any():
raise ValueError(
"Randomization term 'randomize_fixed_tendon_parameters' is setting lower tendon limits that are"
" greater than upper tendon limits."
self.asset.set_fixed_tendon_offset_index(
offset=offset[env_ids[:, None], tendon_ids], fixed_tendon_ids=tendon_ids, env_ids=env_ids
)
self.asset.set_fixed_tendon_position_limit_index(
limit=tendon_limits, fixed_tendon_ids=tendon_ids, env_ids=env_ids
)

# rest length
if rest_length_distribution_params is not None:
rest_length = _randomize_prop_by_op(
self.asset.data.fixed_tendon_rest_length.torch.clone(),
rest_length_distribution_params,
env_ids,
tendon_ids,
operation=operation,
distribution=distribution,
)
self.asset.set_fixed_tendon_rest_length_index(
rest_length=rest_length[env_ids[:, None], tendon_ids], fixed_tendon_ids=tendon_ids, env_ids=env_ids
)

# offset
if offset_distribution_params is not None:
offset = _randomize_prop_by_op(
self.asset.data.fixed_tendon_offset.torch.clone(),
offset_distribution_params,
env_ids,
tendon_ids,
operation=operation,
distribution=distribution,
)
self.asset.set_fixed_tendon_offset_index(
offset=offset[env_ids[:, None], tendon_ids], fixed_tendon_ids=tendon_ids, env_ids=env_ids
)
else:
raise NotImplementedError("Offset is not supported in Newton.")

# write the fixed tendon properties into the simulation
self.asset.write_fixed_tendon_properties_to_sim_index(env_ids=env_ids)
Expand Down
28 changes: 18 additions & 10 deletions source/isaaclab/isaaclab/sim/schemas/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -877,23 +877,31 @@ def modify_fixed_tendon_properties(

# get USD prim
tendon_prim = stage.GetPrimAtPath(prim_path)
# check if prim has fixed tendon applied on it
# check if prim has fixed tendon applied on it or if the mjc tendon prim exiss
applied_schemas = tendon_prim.GetAppliedSchemas()
if not any("PhysxTendonAxisRootAPI" in s for s in applied_schemas):
prim_type = tendon_prim.GetTypeName()
if not any("PhysxTendonAxisRootAPI" in s for s in applied_schemas) and prim_type != "MjcTendon":
return False

# resolve all available instances of the schema since it is multi-instance
cfg = cfg.to_dict()
for schema_name in applied_schemas:
if "PhysxTendonAxisRootAPI" not in schema_name:
continue
# set into PhysX API by attribute prefix schema_name: (e.g. PhysxTendonAxisRootAPI:default:stiffness)
if prim_type != "MjcTendon":
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.

I think MjcTendon is newton specific so it may need to be added to new newton schema. #5049 has example how physx setup is done. @ooctipus could you also help suggest here?

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.

I think there are other mujoco schema also got leaked into core schema. and also seems like we have not prepared a home for mujoco schema under isaaclab_newton properly. This check is no ideal but probably makes sense for this PR, and would require follow up work to split it.

for schema_name in applied_schemas:
if "PhysxTendonAxisRootAPI" not in schema_name:
continue
# set into PhysX API by attribute prefix schema_name: (e.g. PhysxTendonAxisRootAPI:default:stiffness)
for attr_name, value in cfg.items():
safe_set_attribute_on_usd_prim(
tendon_prim,
f"{schema_name}:{to_camel_case(attr_name, 'cC')}",
value,
camel_case=False,
)
else:
# only stiffness and damping in the cfg map to mjc attributes
for attr_name, value in cfg.items():
safe_set_attribute_on_usd_prim(
tendon_prim,
f"{schema_name}:{to_camel_case(attr_name, 'cC')}",
value,
camel_case=False,
tendon_prim, f"mjc:{to_camel_case(attr_name, 'cC')}", value, camel_case=False
)
# success
return True
Expand Down
3 changes: 3 additions & 0 deletions source/isaaclab_newton/changelog.d/passive-tendons.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Added
^^^^^
* Updates articulation to support passive tendons properties
Loading
Loading