Skip to content

Adds Assemble Trocar Task#5066

Open
mingxueg-nv wants to merge 2 commits intoisaac-sim:developfrom
mingxueg-nv:Adds_Assemble_Trocar_for_RLinf
Open

Adds Assemble Trocar Task#5066
mingxueg-nv wants to merge 2 commits intoisaac-sim:developfrom
mingxueg-nv:Adds_Assemble_Trocar_for_RLinf

Conversation

@mingxueg-nv
Copy link
Contributor

Description

Adds the Assemble Trocar manipulation task for the Unitree G1 (29-DoF + Dex3), with RLinf support.

Key additions:

  • Task MDP: observations (body + Dex3 joint states), reward functions (4-stage sparse), termination conditions (timeout, success, object drop), and reset events (scene reset, task stage reset, random tray rotation).
  • Camera presets: front camera and left/right wrist cameras (TiledCamera, 224×224) configured for GR00T visual input.
  • Robot presets: G1 29-DoF + Dex3 articulation configuration.
  • GR00T data config: IsaacLabDataConfig defining video/state/action modality keys, transforms (SinCos state encoding, min-max action normalization, color jitter), and model-specific settings.
  • RLinf extension update: minor update to isaaclab_contrib/rl/rlinf/extension.py to support the new task registration.

Type of change

  • New feature (non-breaking change which adds functionality)

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with ./isaaclab.sh --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the changelog and the corresponding version in the extension's config/extension.toml file
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

@mingxueg-nv mingxueg-nv requested a review from Mayankm96 as a code owner March 20, 2026 08:40
@github-actions github-actions bot added the isaac-lab Related to Isaac Lab team label Mar 20, 2026
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 20, 2026

Greptile Summary

This PR adds the Assemble Trocar manipulation task for the Unitree G1 (29-DoF + Dex3) robot, including a 4-stage MDP (lift → tip-align → insert → place), camera presets, a GR00T data config, and a minor RLinf extension patch for render warm-up on reset. The overall architecture follows established IsaacLab task conventions, but there are two blocking issues that prevent the task from running for any user other than the author:

  • Missing env config module (g129_dex3_env_cfg): __init__.py imports and registers gym environments from this module, which is not present in the PR. Every import of the task package will raise an ImportError.
  • Hardcoded local asset path (robot_config.py): The USD robot asset path is hardcoded to /localhome/local-mingxueg/mingxue/assets/..., which will fail for all other users.

Additional issues found:

  • observations.py uses module-level global caches (_body_obs_cache, _dex3_obs_cache) that are shared across all env instances in a process, causing silent data corruption when a training env and eval env run simultaneously.
  • rewards.py calls .item() on a batch-shaped is_parallel tensor during debug logging, which will crash with RuntimeError when num_envs > 1 and print_log=True.
  • extension.py directly mutates _rtx_utils._last_render_update_key, a private renderer variable, which is brittle across Isaac Sim versions.
  • A misleading comment in gr00t_config.py states cameras already output 224×224 while the video resize transforms are in fact active and needed.

Confidence Score: 1/5

  • Not safe to merge — the task cannot be loaded or run by any user other than the author due to a missing module import and a hardcoded local file path.
  • Two critical blocking bugs prevent the task from functioning at all: (1) the gym registration imports a non-existent module causing an immediate ImportError, and (2) the robot asset uses a hardcoded path to the author's local machine. These must be resolved before any other review concerns can be evaluated in practice.
  • assemble_trocar/__init__.py (missing module), config/robot_config.py (hardcoded asset path), mdp/observations.py (shared global cache), and mdp/rewards.py (batch .item() crash).

Important Files Changed

Filename Overview
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/assemble_trocar/config/robot_config.py Contains a hardcoded absolute path to the author's local machine for the USD robot asset, making the task non-portable and non-functional for all other users.
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/assemble_trocar/init.py Imports g129_dex3_env_cfg which is not included in the PR and does not exist; the gym registrations will raise an ImportError at load time, blocking the task entirely.
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/assemble_trocar/mdp/rewards.py 4-stage sparse/dense reward system is well-structured; contains a .item() call on a batch tensor in debug logging that will crash when num_envs > 1 and print_log=True.
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/assemble_trocar/mdp/observations.py Observation helpers use module-level global caches that will be silently overwritten if multiple env instances run in the same process, corrupting observations.
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/assemble_trocar/mdp/events.py Reset events for tray rotation and robot joint positions are logically correct; correctly uses per-env state writes and handles coordinate conversion for multi-env setups.
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/assemble_trocar/mdp/terminations.py Simple, clean termination conditions for timeout, object drop, and task success; reads shared stage state correctly.
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/assemble_trocar/config/camera_config.py Camera presets are well-organized; wrist cameras are configured at 480×640 (resized to 224×224 in the GR00T transform pipeline), which works correctly despite a misleading comment in gr00t_config.py.
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/assemble_trocar/config/gr00t_config.py GR00T data config is reasonable; contains a contradictory comment claiming cameras output 224×224 while the transforms actively resize from 480×640, which will confuse future maintainers.
source/isaaclab_contrib/isaaclab_contrib/rl/rlinf/extension.py Adds a render warm-up patch via monkey-patching env.reset; directly mutates a private internal variable (_last_render_update_key) of the renderer module, which is fragile across Isaac Sim versions.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    S0["Stage 0: Initial\n(trocars on tray)"]
    S1["Stage 1: Lifted\n(both trocars above table)"]
    S2["Stage 2: Tip Aligned\n(trocar tips within 15 mm)"]
    S3["Stage 3: Inserted\n(parallel + centers < 30 mm)"]
    S4["Stage 4: Placed\n(both in target zone)"]
    TERM_TIMEOUT["Terminate: Timeout"]
    TERM_DROP["Terminate: Object Drop\n(z < 0.5 m)"]
    TERM_SUCCESS["Terminate: Success"]

    S0 -->|"lift_trocars_reward\nboth z > table+0.05"| S1
    S1 -->|"trocar_tip_alignment_reward\ntip_dist < 0.015 m"| S2
    S2 -->|"trocar_insertion_reward\nparallel + center < 0.03 m"| S3
    S3 -->|"trocar_placement_reward\nboth in XY zone"| S4

    S0 & S1 & S2 & S3 --> TERM_TIMEOUT
    S0 & S1 & S2 & S3 --> TERM_DROP
    S4 --> TERM_SUCCESS
Loading

Comments Outside Diff (2)

  1. source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/assemble_trocar/config/gr00t_config.py, line 375-387 (link)

    P2 Contradictory comment about camera resolution

    The comment on line 375–379 says "camera already outputs 224×224 via TiledCameraCfg" and implies VideoCrop/VideoResize should be disabled, yet both VideoCrop and VideoResize are actively applied immediately below (lines 380–386). In camera_config.py, wrist cameras are configured at 480×640 (the default resolution). The crop+resize pipeline is therefore necessary and the comment is misleading. The dead-code comment should be removed or updated to reflect that the transforms are intentionally active to resize from the native camera resolution to 224×224 for GR00T input.

  2. source/isaaclab_contrib/isaaclab_contrib/rl/rlinf/extension.py, line 21-27 (link)

    P2 Directly mutating a private module-level variable

    _rtx_utils._last_render_update_key = (0, -1) directly overwrites a private, underscore-prefixed module attribute of isaaclab_physx.renderers.isaac_rtx_renderer_utils. This is very fragile: the attribute name, type, and semantics are internal implementation details that can change without notice in any renderer update, silently breaking the warm-up logic. Consider whether there is a public API on env.sim or env.render() that can achieve the same render warm-up effect without reaching into private state.

Last reviewed commit: "Adds Assemble Trocar..."

Comment on lines +616 to +617
f"is_parallel={is_parallel.item()} | reward={reward[0].item():.3f}"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

P1 .item() called on a batch tensor

is_parallel has shape (num_envs,). Calling .item() on it will raise a RuntimeError: only one element tensors can be converted to Python scalars whenever num_envs > 1 and print_log=True. The fix is to index into the first environment:

Suggested change
f"is_parallel={is_parallel.item()} | reward={reward[0].item():.3f}"
)
f" └─ Stage 2 (Push In, {mode_str}): angle={angle[0].item():.3f} | "
f"center_d={center_dist[0].item():.4f} | "
f"is_parallel={is_parallel[0].item()} | reward={reward[0].item():.3f}"

Comment on lines +39 to +48
_body_obs_cache = {
"device": None,
"batch": None,
"idx_t": None,
"idx_batch": None,
"pos_buf": None,
"vel_buf": None,
"torque_buf": None,
"combined_buf": None,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

P1 Module-level global cache breaks multi-instance and reloading scenarios

_body_obs_cache (and _dex3_obs_cache) are module-level mutable dicts. If two ManagerBasedRLEnv instances exist simultaneously (e.g., a training env and an eval env in the same process), both will share and overwrite the same cache, producing corrupted observations for one of them. The cache should either be keyed by id(env) or stored per-env instance (e.g., via setattr(env, '_body_obs_cache', ...)), consistent with how get_trocar_tip_position in rewards.py correctly uses setattr(env, cache_key, ...).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

isaac-lab Related to Isaac Lab team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant