-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Implements passive fixed tendons with mjwarp #5522
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 12 commits
80cf81f
ceb6579
6834867
6e82fe5
2cfebd9
183022a
27a551b
f5f43d4
3a54517
2744b3e
aa87f5f
e054aa2
c7dd84d
99b1a61
614dbb6
5b2f873
4b50d5f
997200d
ad103b4
40135b6
f963a5a
fdf2197
a2ded62
b8c6a88
db60dfc
2c0ac85
3d0a74f
2512c92
26b6e41
f4f71f9
2cc82be
d48b845
29068bf
d32c593
bda9004
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1472,6 +1472,12 @@ def __init__(self, cfg: EventTermCfg, env: ManagerBasedEnv): | |
| f" '{cfg.params['operation']}'." | ||
| ) | ||
|
|
||
| manager_name = env.sim.physics_manager.__name__.lower() | ||
| if "newton" in manager_name: | ||
| self.newton = True | ||
| else: | ||
| self.newton = False | ||
|
|
||
| def __call__( | ||
| self, | ||
| env: ManagerBasedEnv, | ||
|
|
@@ -1528,80 +1534,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 not self.newton: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this would become _backend == "physx" if we use the above comment
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| 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 not self.newton: | ||
| 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 not self.newton: | ||
| 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 not self.newton: | ||
| 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) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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": | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| Added | ||
| ^^^^^ | ||
| * Updates articulation to support passive tendons properties |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other places in this file _backend is used, let's use the same convention
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done