Skip to content
Merged
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: 2 additions & 2 deletions docs/source/overview/sim/sim_articulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Articulations are configured using the {class}`~cfg.ArticulationCfg` dataclass.

### Drive Configuration

The `drive_props` parameter controls the joint physics behavior. It is defined using the `JointDrivePropertiesCfg` class.
The `drive_props` parameter controls the joint physics behavior. It is defined using the `JointDrivePropertiesCfg` class. For articulation object without internal drive force, like cabinet and drawer, better set `drive_type` to `"none"`.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor grammar/style: "For articulation object ... better set" is awkward English and could be misread. Consider rephrasing (e.g., "For articulations without internal drive force (e.g., cabinets/drawers), it's better to set drive_type to "none".").

Suggested change
The `drive_props` parameter controls the joint physics behavior. It is defined using the `JointDrivePropertiesCfg` class. For articulation object without internal drive force, like cabinet and drawer, better set `drive_type` to `"none"`.
The `drive_props` parameter controls the joint physics behavior. It is defined using the `JointDrivePropertiesCfg` class. For articulations without internal drive force (e.g., cabinets and drawers), it's better to set `drive_type` to `"none"`.

Copilot uses AI. Check for mistakes.

Comment on lines 25 to 28
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation refers to drive_props, but the actual config field used throughout the codebase (and other docs) is drive_pros. Using the wrong name here is confusing and can lead users to pass an unsupported parameter name.

Copilot uses AI. Check for mistakes.
| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
Expand All @@ -33,7 +33,7 @@ The `drive_props` parameter controls the joint physics behavior. It is defined u
| `max_effort` | `float` / `Dict` | `1.0e10` | Maximum effort (force/torque) the joint can exert. |
| `max_velocity` | `float` / `Dict` | `1.0e10` | Maximum velocity allowed for the joint ($m/s$ or $rad/s$). |
| `friction` | `float` / `Dict` | `0.0` | Joint friction coefficient. |
| `drive_type` | `str` | `"force"` | Drive mode: `"force"`(driven by a force), `"acceleration"`(driven by an acceleration) or `none`(no force). |
| `drive_type` | `str` | `"none"` | Drive mode: `"force"`(driven by a force), `"acceleration"`(driven by an acceleration) or `none`(no force). |
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs list the default drive_type as "none", but the actual config default is still "force" (JointDrivePropertiesCfg.drive_type = "force" in embodichain/lab/sim/cfg.py:502). Either update the code default (if intended) or correct this documentation default to avoid confusing users.

Suggested change
| `drive_type` | `str` | `"none"` | Drive mode: `"force"`(driven by a force), `"acceleration"`(driven by an acceleration) or `none`(no force). |
| `drive_type` | `str` | `"force"` | Drive mode: `"force"`(driven by a force), `"acceleration"`(driven by an acceleration) or `none`(no force). |

Copilot uses AI. Check for mistakes.

### Setup & Initialization

Expand Down
1 change: 1 addition & 0 deletions docs/source/overview/sim/sim_assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ Configured via `LightCfg`.
sim_rigid_object.md
sim_rigid_object_group.md
sim_cloth.md
sim_soft_object.md
sim_articulation.md
sim_robot.md
Expand Down
168 changes: 168 additions & 0 deletions docs/source/overview/sim/sim_cloth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# Cloth Object

```{currentmodule} embodichain.lab.sim
```

The {class}`~objects.Cloth` class represents deformable surface entities in EmbodiChain. Unlike rigid bodies, cloth objects are defined by vertices and meshes rather than a single rigid pose.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

objects.Cloth doesn’t appear to exist in the codebase (the implementation/export is objects.ClothObject). The class reference here should be updated so the docs resolve correctly.

Suggested change
The {class}`~objects.Cloth` class represents deformable surface entities in EmbodiChain. Unlike rigid bodies, cloth objects are defined by vertices and meshes rather than a single rigid pose.
The {class}`~objects.ClothObject` class represents deformable surface entities in EmbodiChain. Unlike rigid bodies, cloth objects are defined by vertices and meshes rather than a single rigid pose.

Copilot uses AI. Check for mistakes.

## Configuration

Configured via {class}`~cfg.ClothObjectCfg`.
Comment on lines +6 to +10
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs refer to {class}~objects.Cloth here, but the codebase exports `ClothObject` (see `embodichain/lab/sim/objects/cloth_object.py`). Unless there is an alias not shown here, this should likely be `{class}`~objects.ClothObject to avoid broken references in the generated docs.

Copilot uses AI. Check for mistakes.

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `physical_attr` | `ClothPhysicalAttributesCfg` | `...` | Physical attributes. |
| `shape` | `MeshCfg` | `MeshCfg()` | Mesh configuration. |

### CLoth Body Attributes
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section title typo: ### CLoth Body Attributes has inconsistent capitalization. Consider renaming to ### Cloth Body Attributes for consistency and readability.

Suggested change
### CLoth Body Attributes
### Cloth Body Attributes

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in heading: "CLoth" should be "Cloth".

Suggested change
### CLoth Body Attributes
### Cloth Body Attributes

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section title has a capitalization typo: "CLoth" -> "Cloth".

Suggested change
### CLoth Body Attributes
### Cloth Body Attributes

Copilot uses AI. Check for mistakes.

Cloth bodies require both voxelization and physical attributes.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence says cloth bodies require "voxelization", but ClothObjectCfg only has physical_attr and shape (no voxelization config like SoftObjectCfg has). Consider removing the voxelization reference to keep the cloth docs accurate.

Suggested change
Cloth bodies require both voxelization and physical attributes.
Cloth bodies require both a mesh shape and physical attributes.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +19
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section says cloth bodies require "voxelization", but ClothObjectCfg only has shape and physical_attr (no voxelization attributes). Please revise this text to describe the actual cloth configuration requirements.

Suggested change
### CLoth Body Attributes
Cloth bodies require both voxelization and physical attributes.
### Cloth Body Attributes
Cloth bodies are configured using a mesh shape ({class}`~cfg.MeshCfg` via the `shape` field) and physical attributes ({class}`~cfg.ClothPhysicalAttributesCfg` via the `physical_attr` field).

Copilot uses AI. Check for mistakes.

**Physical Attributes ({class}`~cfg.ClothPhysicalAttributesCfg`)**

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `youngs` | `float` | `1e10` | Young's modulus (higher = stiffer). |
| `poissons` | `float` | `0.3` | Poisson's ratio. |
| `dynamic_friction` | `float` | `0.5` | Dynamic friction coefficient. |
| `elasticity_damping` | `float` | `0.0` | Elasticity damping factor. |
| `thickness` | `float` | `0.01` | Cloth thickness (m). |
| `bending_stiffness` | `float` | `0.001` | Bending stiffness. |
| `bending_damping` | `float` | `0.0` | Bending damping. |
| `enable_kinematic` | `bool` | `False` | If True, (partially) kinematic behavior is enabled. |
| `enable_ccd` | `bool` | `True` | Enable continuous collision detection (CCD). |
| `enable_self_collision` | `bool` | `False` | Enable self-collision handling. |
| `has_gravity` | `bool` | `True` | Whether the cloth is affected by gravity. |
| `self_collision_stress_tolerance` | `float` | `0.9` | Stress tolerance threshold for self-collision constraints. |
| `collision_mesh_simplification` | `bool` | `True` | Whether to simplify the collision mesh for self-collision. |
| `vertex_velocity_damping` | `float` | `0.005` | Per-vertex velocity damping. |
| `mass` | `float` | `-1.0` | Total mass of the cloth. If negative, density is used to compute mass. |
| `density` | `float` | `1.0` | Material density in kg/m^3. |
| `max_depenetration_velocity` | `float` | `1e6` | Maximum velocity used to resolve penetrations. |
| `max_velocity` | `float` | `100.0` | Clamp for linear (or vertex) velocity. |
| `self_collision_filter_distance` | `float` | `0.1` | Distance threshold for filtering self-collision vertex pairs. |
| `linear_damping` | `float` | `0.05` | Global linear damping applied to the cloth. |
| `sleep_threshold` | `float` | `0.05` | Velocity/energy threshold below which the cloth can go to sleep. |
| `settling_threshold` | `float` | `0.1` | Threshold used to decide convergence/settling state. |
| `settling_damping` | `float` | `10.0` | Additional damping applied during settling phase. |
| `min_position_iters` | `int` | `4` | Minimum solver iterations for position correction. |
| `min_velocity_iters` | `int` | `1` | Minimum solver iterations for velocity updates. |

For Cloth Object tutorial, please refer to the [Cloth Body Simulation](https://dexforce.github.io/EmbodiChain/tutorial/create_cloth.html).


### Setup & Initialization

```python
import torch
from embodichain.lab.sim import SimulationManager, SimulationManagerCfg
from embodichain.lab.sim.objects import ClothObject, ClothObjectCfg
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setup code example references o3d, os, tempfile, MeshCfg, and ClothPhysicalAttributesCfg but they aren’t imported in the snippet, so it won’t run as written. Add the missing imports (or remove those references) to keep the example executable.

Suggested change
from embodichain.lab.sim.objects import ClothObject, ClothObjectCfg
from embodichain.lab.sim.objects import ClothObject, ClothObjectCfg
from embodichain.lab.sim.cfg import MeshCfg, ClothPhysicalAttributesCfg
import os
import tempfile
import open3d as o3d

Copilot uses AI. Check for mistakes.


def create_2d_grid_mesh(width: float, height: float, nx: int = 1, ny: int = 1):
"""Create a flat rectangle in the XY plane centered at `origin`.

The rectangle is subdivided into an `nx` by `ny` grid (cells) and
triangulated. `nx=1, ny=1` yields the simple two-triangle rectangle.

Returns an vertices and triangles.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar issue in the example docstring: "Returns an vertices and triangles." should be corrected (e.g., "Returns vertices and triangles."), otherwise it reads incorrectly in the rendered documentation.

Suggested change
Returns an vertices and triangles.
Returns vertices and triangles.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small docstring grammar issue in the example: "Returns an vertices and triangles." should be corrected (e.g., "Returns vertices and triangles.")

Suggested change
Returns an vertices and triangles.
Returns vertices and triangles.

Copilot uses AI. Check for mistakes.
"""
w = float(width)
h = float(height)
if nx < 1 or ny < 1:
raise ValueError("nx and ny must be >= 1")

# Vectorized vertex positions using PyTorch
x_lin = torch.linspace(-w / 2.0, w / 2.0, steps=nx + 1, dtype=torch.float64)
y_lin = torch.linspace(-h / 2.0, h / 2.0, steps=ny + 1, dtype=torch.float64)
yy, xx = torch.meshgrid(y_lin, x_lin) # shapes: (ny+1, nx+1)
xx_flat = xx.reshape(-1)
yy_flat = yy.reshape(-1)
zz_flat = torch.full_like(xx_flat, 0, dtype=torch.float64)
verts = torch.stack([xx_flat, yy_flat, zz_flat], dim=1) # (Nverts, 3)

# Vectorized triangle indices
idx = torch.arange((nx + 1) * (ny + 1), dtype=torch.int64).reshape(ny + 1, nx + 1)
v0 = idx[:-1, :-1].reshape(-1)
v1 = idx[:-1, 1:].reshape(-1)
v2 = idx[1:, :-1].reshape(-1)
v3 = idx[1:, 1:].reshape(-1)
tri1 = torch.stack([v0, v1, v3], dim=1)
tri2 = torch.stack([v0, v3, v2], dim=1)
faces = torch.cat([tri1, tri2], dim=0).to(torch.int32)
return verts, faces

# 1. Initialize Simulation
device = "cuda" if torch.cuda.is_available() else "cpu"
sim_cfg = SimulationManagerCfg(sim_device=device)
sim = SimulationManager(sim_config=sim_cfg)

cloth_verts, cloth_faces = create_2d_grid_mesh(width=0.3, height=0.3, nx=12, ny=12)
cloth_mesh = o3d.geometry.TriangleMesh(
vertices=o3d.utility.Vector3dVector(cloth_verts.to("cpu").numpy()),
triangles=o3d.utility.Vector3iVector(cloth_faces.to("cpu").numpy()),
)
Comment on lines +100 to +104
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setup code block uses o3d, os, and tempfile, but they are not imported in this snippet. Consider adding the missing imports (or explicitly noting the snippet is partial) to prevent copy/paste errors.

Copilot uses AI. Check for mistakes.
cloth_save_path = os.path.join(tempfile.gettempdir(), "cloth_mesh.ply")
o3d.io.write_triangle_mesh(cloth_save_path, cloth_mesh)
# 2. Configure Cloth Object
cfg=ClothObjectCfg(
uid="cloth_demo",
shape=MeshCfg(fpath=cloth_save_path),
init_pos=[0.5, 0.0, 0.3],
Comment on lines +107 to +111
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setup code block references MeshCfg and ClothPhysicalAttributesCfg (used in shape=... / physical_attr=...), but the snippet only imports ClothObject/ClothObjectCfg. Consider adding the missing imports so the example is self-contained.

Copilot uses AI. Check for mistakes.
init_rot=[0, 0, 0],
physical_attr=ClothPhysicalAttributesCfg(
mass=0.01,
youngs=1e10,
poissons=0.4,
thickness=0.04,
bending_stiffness=0.01,
bending_damping=0.1,
dynamic_friction=0.95,
min_position_iters=30,
),
)

# 3. Spawn Cloth Object
# Note: Assuming the method in SimulationManager is 'add_cloth_object'
cloth_object: ClothObject = sim.add_cloth_object(cfg=cfg)

# 4. Initialize Physics
sim.reset_objects_state()
```
### Cloth Object Class
#### Vertex Data (Observation)
For cloth objects, the state is represented by the positions and velocities of its vertices, rather than a single root pose.

| Method | Return Shape | Description |
| :--- | :--- | :--- |
| `get_current_vertex_position()` | `(n_envs, n_vert, 3)` | Current positions of mesh vertices. |
| `get_current_vertex_velocity()` | `(n_envs, n_vert, 3)` | Current positions of mesh vertices. |
| `get_rest_vertex_position()` | `(n_envs, n_vert, 3` | Rest (initial) positions of collision vertices. |
Comment on lines +139 to +140
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The vertex API table has a couple of correctness issues: get_current_vertex_velocity() is described as returning positions (should describe velocities), and get_rest_vertex_position()'s return shape is missing a closing parenthesis/backtick. These will confuse readers and should be corrected.

Suggested change
| `get_current_vertex_velocity()` | `(n_envs, n_vert, 3)` | Current positions of mesh vertices. |
| `get_rest_vertex_position()` | `(n_envs, n_vert, 3` | Rest (initial) positions of collision vertices. |
| `get_current_vertex_velocity()` | `(n_envs, n_vert, 3)` | Current velocities of mesh vertices. |
| `get_rest_vertex_position()` | `(n_envs, n_vert, 3)` | Rest (initial) positions of collision vertices. |

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return shape formatting is broken for get_rest_vertex_position() (missing closing parenthesis/backtick). This will render incorrectly and is ambiguous.

Suggested change
| `get_rest_vertex_position()` | `(n_envs, n_vert, 3` | Rest (initial) positions of collision vertices. |
| `get_rest_vertex_position()` | `(n_envs, n_vert, 3)` | Rest (initial) positions of collision vertices. |

Copilot uses AI. Check for mistakes.

> Note: N is the number of environments/instances, V_col is the number of collision vertices, and V_sim is the number of simulation vertices.

```python
# Example: Accessing vertex data
vert_position = cloth_object.get_current_vertex_position()
print(f"vertices positions: {vert_position}")

vert_velocity = cloth_object.get_current_vertex_velocity()
print(f"Vertex Velocities: {vert_velocity}")
```
#### Pose Management
You can set the global pose of a cloth object (which transforms all its vertices), but getting a single "pose" from a deformed surface object is not supported.

| Method | Description |
| :--- | :--- |
| `set_local_pose(pose)` | Sets the pose of the object by transforming all vertices. |
| `get_local_pose()` | **Not Supported**. Raises `NotImplementedError` because a deformed object does not have a single rigid pose. |


```python
# Reset or Move the Cloth Object
target_pose = torch.tensor([[0, 0, 1.0, 1, 0, 0, 0]], device=device) # (x, y, z, qw, qx, qy, qz)
cloth_object.set_local_pose(target_pose)

# Important: Step simulation to apply changes
sim.update()
```
2 changes: 1 addition & 1 deletion docs/source/overview/sim/sim_soft_object.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
```{currentmodule} embodichain.lab.sim
```

The {class}`~objects.SoftObject` class represents deformable entities (e.g., cloth, sponges, soft robotics) in EmbodiChain. Unlike rigid bodies, soft objects are defined by vertices and meshes rather than a single rigid pose.
The {class}`~objects.SoftObject` class represents deformable entities (e.g. sponges, soft robotics) in EmbodiChain. Unlike rigid bodies, soft objects are defined by vertices and meshes rather than a single rigid pose.

## Configuration

Expand Down
3 changes: 1 addition & 2 deletions docs/source/tutorial/create_cloth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ The grid mesh generated earlier is saved to disk and then passed to :meth:`Simul
.. literalinclude:: ../../../scripts/tutorials/sim/create_cloth.py
:language: python
:start-at: cloth_verts, cloth_faces = create_2d_grid_mesh
:end-at: )
:end-before: padding_box_cfg
:end-at: padding_box_cfg = RigidObjectCfg
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This literalinclude now ends at the line containing padding_box_cfg = RigidObjectCfg, which in the referenced script is the start of a multi-line call. This will include an incomplete statement (unclosed parenthesis) in the rendered docs. Consider ending before padding_box_cfg (e.g., using :end-before:) or ending at the closing ) of the cloth spawn block so the snippet is syntactically complete.

Suggested change
:end-at: padding_box_cfg = RigidObjectCfg
:end-before: padding_box_cfg = RigidObjectCfg(

Copilot uses AI. Check for mistakes.

Adding a rigid body for interaction
-------------------------------------
Expand Down
5 changes: 4 additions & 1 deletion embodichain/lab/sim/cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ class ArticulationCfg(ObjectBaseCfg):
fpath: str = None
"""Path to the articulation asset file."""

drive_pros: JointDrivePropertiesCfg = JointDrivePropertiesCfg()
drive_pros: JointDrivePropertiesCfg = JointDrivePropertiesCfg(drive_type="none")
"""Properties to define the drive mechanism of a joint."""

body_scale: Union[tuple, list] = (1.0, 1.0, 1.0)
Expand Down Expand Up @@ -1174,6 +1174,9 @@ class RobotCfg(ArticulationCfg):
"""Configuration for a robot asset in the simulation.
"""

drive_pros: JointDrivePropertiesCfg = JointDrivePropertiesCfg(drive_type="force")
"""Properties to define the drive mechanism of a joint."""

control_parts: Dict[str, List[str]] | None = None
"""Control parts is the mapping from part name to joint names.

Expand Down
2 changes: 1 addition & 1 deletion embodichain/lab/sim/objects/articulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1235,7 +1235,7 @@ def set_joint_drive(
max_effort: torch.Tensor | None = None,
max_velocity: torch.Tensor | None = None,
friction: torch.Tensor | None = None,
drive_type: str = "force",
drive_type: str = "none",
joint_ids: Sequence[int] | None = None,
env_ids: Sequence[int] | None = None,
Comment on lines 1236 to 1240
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drive_type now defaults to "none", but the docstring parameter description still states it defaults to "force". This is misleading for API consumers; please update the docstring to match the new default (and adjust any related wording if needed).

Copilot uses AI. Check for mistakes.
Comment on lines 1236 to 1240
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The drive_type parameter default was changed to "none", but the docstring still says it defaults to "force". Please update the docstring to match the new default so callers aren’t misled.

Copilot uses AI. Check for mistakes.
) -> None:
Comment on lines 1237 to 1241
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drive_type now defaults to "none" in the signature, but the docstring below still states the default is "force". Please update the docstring to avoid misleading API docs.

Copilot uses AI. Check for mistakes.
Expand Down
35 changes: 35 additions & 0 deletions embodichain/lab/sim/objects/robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,41 @@ def _init_control_parts(self, control_parts: Dict[str, List[str]]) -> None:
# Initialize control groups
self._control_groups = self._extract_control_groups()

def set_joint_drive(
self,
stiffness: torch.Tensor | None = None,
damping: torch.Tensor | None = None,
max_effort: torch.Tensor | None = None,
max_velocity: torch.Tensor | None = None,
friction: torch.Tensor | None = None,
drive_type: str = "force",
joint_ids: Sequence[int] | None = None,
env_ids: Sequence[int] | None = None,
) -> None:
Comment on lines +795 to +805
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding this override changes the default drive_type only for explicit calls to Robot.set_joint_drive(). It does not prevent robots from initializing with drive_type="none" via RobotCfg inheriting ArticulationCfg’s new default. If the intent is for Robot defaults to remain "force", consider also overriding drive_pros in RobotCfg (or adjusting Robot’s initialization fallback).

Copilot uses AI. Check for mistakes.
"""Set the drive properties for the robot.
Different from Articulation, default drive type is 'force' instead of 'none'

Args:
stiffness (torch.Tensor): The stiffness of the joint drive with shape (len(env_ids), len(joint_ids)).
damping (torch.Tensor): The damping of the joint drive with shape (len(env_ids), len(joint_ids)).
max_effort (torch.Tensor): The maximum effort of the joint drive with shape (len(env_ids), len(joint_ids)).
max_velocity (torch.Tensor): The maximum velocity of the joint drive with shape (len(env_ids), len(joint_ids)).
friction (torch.Tensor): The joint friction coefficient with shape (len(env_ids), len(joint_ids)).
drive_type (str, optional): The type of drive to apply. Defaults to "force".
joint_ids (Sequence[int] | None, optional): The joint indices to apply the drive to. If None, applies to all joints. Defaults to None.
env_ids (Sequence[int] | None, optional): The environment indices to apply the drive to. If None, applies to all environments. Defaults to None.
"""
super().set_joint_drive(
stiffness=stiffness,
damping=damping,
max_effort=max_effort,
max_velocity=max_velocity,
friction=friction,
drive_type=drive_type,
joint_ids=joint_ids,
env_ids=env_ids,
)

def _set_default_joint_drive(self) -> None:
"""Set default joint drive parameters based on the configuration."""
import numbers
Expand Down
2 changes: 1 addition & 1 deletion examples/sim/demo/pick_up_cloth.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def parse_arguments():
"--enable_rt", action="store_true", help="Enable ray tracing rendering"
)
parser.add_argument(
"--num_envs", type=int, default=4, help="Number of parallel environments"
"--num_envs", type=int, default=1, help="Number of parallel environments"
)
return parser.parse_args()

Expand Down
2 changes: 1 addition & 1 deletion tests/sim/objects/test_articulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def setup_simulation(self, sim_device):
art_path = get_data_path(ART_PATH)
assert os.path.isfile(art_path)

cfg_dict = {"fpath": art_path}
cfg_dict = {"fpath": art_path, "drive_pros": {"drive_type": "force"}}
self.art: Articulation = self.sim.add_articulation(
cfg=ArticulationCfg.from_dict(cfg_dict)
)
Expand Down
Loading