Skip to content

Conversation

@JuanaDd
Copy link
Contributor

@JuanaDd JuanaDd commented Sep 22, 2025

Description

This PR fixes a bug in actuator initialization where effort limits specified in USD assets were being incorrectly overridden with a very large default value (1.0e9) for explicit actuator models.

Fixes # (issue)

Previously, the ActuatorBase initialization logic would unconditionally fall back to _DEFAULT_MAX_EFFORT_SIM (1.0e9) for explicit actuator models when effort_limit_sim was not explicitly set in the configuration, even when the USD asset contained finite, meaningful effort limit values.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

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

@github-actions github-actions bot added bug Something isn't working isaac-lab Related to Isaac Lab team labels Sep 22, 2025
@github-actions github-actions bot added the asset New asset feature or request label Sep 23, 2025
@JuanaDd JuanaDd force-pushed the effort_limit_bugfix branch from cdb1ddd to 51f3234 Compare September 23, 2025 07:58
@Mayankm96 Mayankm96 moved this to In review in Isaac Lab Oct 10, 2025
@Mayankm96 Mayankm96 changed the title [Bugfix] use effort_limit from USD asset if not specified in cfg Uses effort_limit from USD asset if not specified in articulation cfg Oct 10, 2025
@Mayankm96 Mayankm96 changed the title Uses effort_limit from USD asset if not specified in articulation cfg Uses effort_limit from USD asset if not specified in actuator cfg Oct 10, 2025
@Mayankm96 Mayankm96 changed the title Uses effort_limit from USD asset if not specified in actuator cfg Uses effort_limit from USD if not specified in actuator cfg Oct 10, 2025
@ooctipus
Copy link
Collaborator

ooctipus commented Oct 17, 2025

I will propose my solution to this @Mayankm96 @JuanaDd let me know what you think.

  1. Regarding effort_limit from USD as effort_limit_sim, not motor level limit,
  2. Deleting below block so no more assumption about -> explicit actuator should have _DEFAULT_MAX_EFFORT_SIM if ActuatorCfg.effort_limit_sim not specified. We want to use USD default instead for that case.
        # For explicit models, we do not want to enforce the effort limit through the solver
        # (unless it is explicitly set)
        if not self.is_implicit_model and self.cfg.effort_limit_sim is None:
            self.cfg.effort_limit_sim = self._DEFAULT_MAX_EFFORT_SIM
  1. for all places we want _DEFAULT_MAX_EFFORT_SIM as effort_limit_sim we mannually define them in ActuatorCfg

This we have the greatest clarity from ActuatorCfg and also minimum code path(carity) for USD-Cfg resolution

@jtigue-bdai
Copy link
Collaborator

@JuanaDd Thanks for looking into this. I agree with the problem. The effort limit values of the USD articulation (and the USD created from urdf importers) should be passed through as effort_limit.

I think it would be good to add more of a note to the documentation on effort_limit and effort_limit_sim explaining the pass through.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

This PR addresses a bug in actuator initialization where USD-specified effort limits were being incorrectly overridden by a very large default value (1.0e9) for explicit actuator models. The fix implements a more nuanced resolution strategy: when effort_limit is not specified in the actuator configuration, explicit actuators now preserve the meaningful effort limits from the USD asset, while implicit actuators continue to enforce limits through the solver. The change modifies the ActuatorBase initialization logic to conditionally select default values based on whether the actuator model is explicit and whether effort_limit_sim is provided in the configuration. Additionally, the articulation.py file now clones effort limit tensors before passing them to actuators, preventing unintended modifications to the original USD data. Comprehensive test coverage was added to validate the three critical scenarios: config matching USD, config overriding USD, and defaulting to USD when config is None.

PR Description Notes:

  • The PR description mentions that the fix allows the ActuatorBase to "fall back" to USD values, but the implementation actually makes explicit actuators use USD values as the primary default when no config is provided, which is a semantic distinction worth noting.

Important Files Changed

Filename Score Overview
source/isaaclab/isaaclab/actuators/actuator_base.py 5/5 Modified effort limit initialization to use USD values as default for explicit actuators when not specified in config
source/isaaclab/isaaclab/assets/articulation/articulation.py 5/5 Added .clone() to effort limit tensor to prevent unintended modifications to original USD data
source/isaaclab/test/assets/test_articulation.py 5/5 Added comprehensive test coverage for three effort limit scenarios with proper assertions

Confidence score: 5/5

  • This PR is safe to merge with minimal risk as it addresses a clear bug with a well-structured fix
  • Score reflects thorough testing, clear logic improvements, and proper separation of concerns between explicit and implicit actuator models
  • No files require special attention; all changes are well-tested and the logic correctly distinguishes between explicit and implicit actuator handling

Sequence Diagram

sequenceDiagram
    participant User
    participant Articulation
    participant ActuatorBase
    participant PhysX

    User->>Articulation: Initialize Articulation(cfg)
    Articulation->>Articulation: _process_actuators_cfg()
    
    Note over Articulation: For each actuator in cfg.actuators
    
    Articulation->>PhysX: get joint properties from USD<br/>(effort_limit, velocity_limit, etc.)
    PhysX-->>Articulation: USD joint properties
    
    Articulation->>ActuatorBase: __init__(cfg, joint_names, joint_ids,<br/>effort_limit=usd_effort_limit, ...)
    
    alt cfg.effort_limit_sim is None AND not implicit model
        ActuatorBase->>ActuatorBase: Set effort_limit_sim = _DEFAULT_MAX_EFFORT_SIM
    end
    
    ActuatorBase->>ActuatorBase: _parse_joint_parameter(cfg.effort_limit_sim, usd_effort_limit)
    Note over ActuatorBase: Stores as self.effort_limit_sim
    
    alt cfg.effort_limit is not None
        ActuatorBase->>ActuatorBase: _parse_joint_parameter(cfg.effort_limit, effort_limit_sim)
    else cfg.effort_limit is None
        ActuatorBase->>ActuatorBase: _parse_joint_parameter(None, usd_effort_limit)
    end
    Note over ActuatorBase: Stores as self.effort_limit
    
    ActuatorBase-->>Articulation: Actuator initialized
    
    Articulation->>PhysX: write_joint_effort_limit_to_sim(actuator.effort_limit_sim)
    Note over PhysX: Sets physics simulation limits
Loading

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

JuanaDd and others added 2 commits October 27, 2025 10:40
Co-authored-by: James Tigue <166445701+jtigue-bdai@users.noreply.github.com>
Signed-off-by: Juana <yvetted@nvidia.com>
Co-authored-by: James Tigue <166445701+jtigue-bdai@users.noreply.github.com>
Signed-off-by: Juana <yvetted@nvidia.com>
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

This review covers only the changes made since the last review, not the entire PR. The latest change is a minor refactoring in the test file that improves code readability. Specifically, the variable name usd_default has been renamed to usd_default_effort_limit to make its purpose more explicit when testing effort limit initialization behavior. This rename aligns with the improved comment on line 1453 that clarifies "usd default effort limit is set to 80", making the test more self-documenting. The test logic, assertions, and behavior remain completely unchanged - this is purely a cosmetic improvement to variable naming that makes the code easier to understand at a glance.

Important Files Changed

Filename Score Overview
source/isaaclab/test/assets/test_articulation.py 5/5 Variable renamed from usd_default to usd_default_effort_limit for clarity

Confidence score: 5/5

  • This change is completely safe to merge with zero risk of introducing bugs or breaking existing functionality.
  • Score reflects that this is a simple variable rename in test code with no behavioral changes - the test assertions remain identical and the renamed variable is only used locally within the test method.
  • No files require special attention as this is a straightforward refactoring change.

1 file reviewed, no comments

Edit Code Review Agent Settings | Greptile

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Signed-off-by: Juana <yvetted@nvidia.com>
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

Note: This review covers only the changes made since the last review, not the entire PR.

The latest changes implement the previously suggested logic fix for effort limit initialization and correct a corresponding variable name typo in the test file. In actuator_base.py, the conditional logic for effort_default assignment has been corrected to properly use USD-provided effort limits when cfg.effort_limit is None, preventing the erroneous fallback to the inflated 1.0e9 default for explicit actuator models. In the test file, the variable reference was corrected from usd_default to usd_default_effort_limit to match the variable declaration on line 1454. These changes ensure that physically meaningful effort limits from USD assets are preserved in the actuator initialization pipeline, which is critical for realistic physics simulation and matches the established pattern for velocity_limit handling.

Important Files Changed

Filename Score Overview
source/isaaclab/isaaclab/actuators/actuator_base.py 5/5 Fixed conditional logic to use USD effort limits when config value is None
source/isaaclab/test/assets/test_articulation.py 5/5 Corrected variable name typo from usd_default to usd_default_effort_limit

Confidence score: 5/5

  • This PR is safe to merge with minimal risk
  • Score reflects straightforward logic corrections that directly address the identified bug, with clear test coverage validating the fix
  • No files require special attention

2 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

This review covers only the changes made since the last review, not the entire PR. The latest changes simplify the effort limit initialization logic in the ActuatorBase class based on previous feedback. The implementation now distinguishes between implicit and explicit actuator models: for explicit models, when cfg.effort_limit_sim is not specified, the effort limit defaults to the USD-provided values (passed via constructor); for implicit models or when cfg.effort_limit_sim is specified, it uses effort_limit_sim. This approach ensures that meaningful effort limits from USD assets are preserved for explicit models while maintaining appropriate behavior for implicit models that enforce limits through the solver.

Important Files Changed

Filename Score Overview
source/isaaclab/isaaclab/actuators/actuator_base.py 5/5 Simplified effort limit initialization logic to properly handle USD defaults for explicit actuator models

Confidence score: 5/5

  • This PR is safe to merge with minimal risk
  • The simplified conditional logic correctly addresses the bug where USD effort limits were being overridden; the implementation properly differentiates between implicit and explicit models and handles the None case for cfg.effort_limit_sim as intended
  • No files require special attention

1 file reviewed, no comments

Edit Code Review Agent Settings | Greptile

@JuanaDd
Copy link
Contributor Author

JuanaDd commented Oct 27, 2025

Hi @jtigue-bdai Could you review my latest commit and check if the documentation is clear enough?

Copy link
Collaborator

@jtigue-bdai jtigue-bdai left a comment

Choose a reason for hiding this comment

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

Looks good. Thanks @JuanaDd

@Mayankm96
Copy link
Contributor

Could you pleaes update the changelog and extension.toml as well? Thanks!

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

Fixed actuator initialization bug where USD effort limits were incorrectly overridden with 1.0e9 for explicit actuators when not specified in config.

Key Changes:

  • Modified ActuatorBase.__init__ to use USD effort_limit values when cfg.effort_limit is None (line 214 in actuator_base.py:214)
  • Added .clone() when passing effort_limit tensor to prevent unintended mutations (articulation.py:1716)
  • Enhanced test coverage with USD default value case (80.0) and improved assertions (test_articulation.py:1428, test_articulation.py:1472-1474)
  • Updated documentation to clarify the distinction between effort_limit (actuator model clipping) and effort_limit_sim (physics engine clipping)

Behavior:

  • Before: When cfg.effort_limit was None, explicit actuators would incorrectly use 1.0e9 instead of USD values
  • After: When cfg.effort_limit is None, actuators correctly use the USD effort limits from the asset definition

Confidence Score: 5/5

  • Safe to merge - well-tested bug fix with clear improvements
  • All changes are focused on fixing the documented bug, with comprehensive test coverage and proper documentation. The logic change correctly implements the intended fallback behavior, and the .clone() addition prevents potential tensor mutation issues.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
source/isaaclab/isaaclab/actuators/actuator_base.py 5/5 Fixed effort limit initialization to use USD values when config is None, added .clone() protection, and improved documentation
source/isaaclab/isaaclab/assets/articulation/articulation.py 5/5 Added .clone() to prevent unintended tensor mutations when passing effort_limit to actuators
source/isaaclab/test/assets/test_articulation.py 5/5 Added test case for USD default value (80.0) and improved test assertions to verify USD fallback behavior

Sequence Diagram

sequenceDiagram
    participant A as Articulation
    participant USD as USD Asset
    participant AB as ActuatorBase.__init__
    participant Parse as _parse_joint_parameter
    
    Note over A,USD: During articulation initialization
    A->>USD: Read joint_effort_limits from PhysX API
    USD-->>A: effort_limit tensor (e.g., 80.0)
    
    Note over A,AB: Creating actuator
    A->>AB: Create actuator with effort_limit=USD_value.clone()
    
    Note over AB: Check if explicit actuator
    AB->>AB: if explicit & cfg.effort_limit_sim is None
    AB->>AB: Set cfg.effort_limit_sim = 1.0e9
    
    Note over AB: Process effort_limit_sim
    AB->>Parse: Parse cfg.effort_limit_sim with USD value
    Parse-->>AB: self.effort_limit_sim (1.0e9 for explicit, USD for implicit)
    
    Note over AB: Process effort_limit
    alt cfg.effort_limit is None
        AB->>AB: effort_default = effort_limit (USD value)
    else cfg.effort_limit is specified
        AB->>AB: effort_default = self.effort_limit_sim
    end
    
    AB->>Parse: Parse cfg.effort_limit with effort_default
    Parse-->>AB: self.effort_limit
    
    Note over AB: Result
    alt cfg.effort_limit is None
        AB-->>A: effort_limit = USD value (80.0)
    else cfg.effort_limit is specified
        AB-->>A: effort_limit = config value
    end
Loading

3 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

This PR fixes a bug where effort limits from USD assets were incorrectly overridden with a large default value (1.0e9) for explicit actuator models when effort_limit was not specified in the configuration.

Key Changes:

  • actuator_base.py:199-215: Modified effort limit resolution logic to use USD values when cfg.effort_limit is None, rather than always falling back to effort_limit_sim
  • articulation.py:1716: Added .clone() to prevent shared tensor references
  • test_articulation.py: Enhanced test coverage with additional test case (80.0) matching USD default, and added proper assertions to verify the fix works correctly for all three scenarios

Impact:
This fix ensures explicit actuator models correctly respect effort limits defined in USD assets when users don't override them in configuration, preventing unrealistic physics behavior.

Confidence Score: 5/5

  • This PR is safe to merge with no blocking issues
  • The bug fix correctly implements the intended logic: when cfg.effort_limit is None, it uses USD values (via the effort_limit constructor parameter) instead of the large default effort_limit_sim. The logic in line 214 is correct (contrary to the previous comment). Comprehensive test coverage validates all three scenarios, documentation improvements clarify the behavior, and the .clone() addition prevents potential tensor aliasing issues.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
source/isaaclab/isaaclab/actuators/actuator_base.py 5/5 Fixed bug where USD effort limits were overridden when cfg.effort_limit is None; improved documentation for effort_limit parameters
source/isaaclab/isaaclab/assets/articulation/articulation.py 5/5 Added .clone() to effort_limit tensor to prevent shared reference issues; minor whitespace change
source/isaaclab/test/assets/test_articulation.py 5/5 Enhanced test coverage with 80.0 parameter value matching USD default; added proper assertions to verify effort_limit behavior in all scenarios

Sequence Diagram

sequenceDiagram
    participant USD as USD Asset
    participant Art as Articulation
    participant AB as ActuatorBase.__init__
    participant Parse as _parse_joint_parameter
    
    USD->>Art: Provides joint_effort_limits
    Art->>AB: Calls __init__(effort_limit=usd_value)
    
    Note over AB: Check cfg.effort_limit
    
    alt cfg.effort_limit is None
        AB->>AB: effort_default = usd_value
        AB->>Parse: parse(None, usd_value)
        Parse-->>AB: Returns usd_value
        Note over AB: USD value preserved ✓
    else cfg.effort_limit is set
        AB->>AB: effort_default = effort_limit_sim
        AB->>Parse: parse(cfg_value, effort_limit_sim)
        Parse-->>AB: Returns cfg_value
        Note over AB: Config overrides USD
    end
    
    AB-->>Art: Actuator with correct effort_limit
Loading

2 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Signed-off-by: Juana <yvetted@nvidia.com>
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

This PR fixes a critical bug where effort limits from USD assets were incorrectly overridden with a very large default value (1.0e9) for explicit actuator models when effort_limit was not specified in the configuration.

Key Changes:

  • Modified ActuatorBase.__init__() to use USD effort_limit values when cfg.effort_limit is None, instead of incorrectly falling back to effort_limit_sim
  • Added .clone() when passing joint_effort_limits tensor to prevent unintended modifications to shared data
  • Enhanced documentation for effort_limit and effort_limit_sim attributes to clarify their different roles in explicit vs implicit actuators
  • Added comprehensive test coverage with USD default value (80.0) validation

Impact:
The fix ensures that finite, physically meaningful effort limits specified in USD assets are properly preserved when users don't explicitly override them in configuration, preventing unrealistic torque values in explicit actuator models.

Confidence Score: 5/5

  • This PR is safe to merge - it fixes a critical bug with proper test coverage and no breaking changes
  • The fix is well-implemented with clear logic, comprehensive tests validate all scenarios (USD match, USD override, USD default), and documentation improvements clarify the intended behavior. The .clone() addition prevents potential side effects.
  • No files require special attention - all changes are straightforward and well-tested

Important Files Changed

File Analysis

Filename Score Overview
source/isaaclab/isaaclab/actuators/actuator_base.py 5/5 Fixed effort_limit initialization to use USD values when cfg.effort_limit is None; improved documentation
source/isaaclab/test/assets/test_articulation.py 5/5 Added comprehensive test cases for effort_limit including USD default (80.0) value scenario
source/isaaclab/isaaclab/assets/articulation/articulation.py 5/5 Added .clone() to prevent unintended modifications to shared tensor data

Sequence Diagram

sequenceDiagram
    participant User as User Config
    participant Art as Articulation
    participant Act as ActuatorBase
    participant USD as USD Asset
    participant PhysX as PhysX Solver

    Note over User,PhysX: Initialization Flow

    USD->>Art: Provides joint effort_limit (e.g., 80.0)
    Art->>Act: Passes effort_limit to constructor
    User->>Act: cfg.effort_limit (None or specified value)
    User->>Act: cfg.effort_limit_sim (None or specified value)

    alt cfg.effort_limit_sim is None AND explicit actuator
        Act->>Act: Set cfg.effort_limit_sim = 1e9
    end

    Act->>Act: Parse effort_limit_sim using USD value
    
    alt cfg.effort_limit is None
        Act->>Act: effort_default = USD effort_limit
        Note right of Act: Uses USD value (80.0)
    else cfg.effort_limit is specified
        Act->>Act: effort_default = effort_limit_sim
        Note right of Act: Uses configured value
    end

    Act->>Act: self.effort_limit = parse(cfg.effort_limit, effort_default)
    Act->>PhysX: Apply effort_limit_sim to PhysX solver
    
    Note over Act,PhysX: Result: USD values preserved when cfg is None
Loading

5 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Signed-off-by: Kelly Guo <kellyg@nvidia.com>
Signed-off-by: Kelly Guo <kellyg@nvidia.com>
Signed-off-by: Kelly Guo <kellyg@nvidia.com>
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

Fixed effort limit initialization bug where USD-specified effort limits were incorrectly overridden for explicit actuator models.

Key Changes:

  • Added .clone() when passing effort_limit tensor to actuator constructor in articulation.py:1716 to prevent unintended memory sharing
  • Updated actuator_base.py:214 to correctly use USD effort limits when cfg.effort_limit is None
  • Enhanced documentation to clarify the difference between effort_limit (for internal actuator clipping) and effort_limit_sim (for PhysX solver)

Previous Issue:
When cfg.effort_limit was None for explicit actuators, the code was using effort_limit_sim (defaulting to 1.0e9) instead of the meaningful USD values, which caused incorrect actuator behavior.

Note on Previous Comment:
The previous comment claiming "logic inverted" at line 199 is incorrect. The current logic effort_default = effort_limit if self.cfg.effort_limit is None else self.effort_limit_sim is correct - when config is None, it uses the USD value (effort_limit parameter), otherwise it uses effort_limit_sim.

Confidence Score: 5/5

  • This PR is safe to merge - it fixes a critical bug with proper test coverage
  • The changes are minimal, well-tested, and correctly fix the effort limit initialization bug. The .clone() addition prevents memory aliasing issues, and the actuator_base.py logic is correct despite the misleading previous comment. The PR includes comprehensive unit tests that verify all three effort limit scenarios.
  • No files require special attention - all changes are correct and well-implemented

Important Files Changed

File Analysis

Filename Score Overview
source/isaaclab/isaaclab/assets/articulation/articulation.py 5/5 Added .clone() to effort_limit tensor to prevent unintended reference sharing with the actuator, ensuring independent effort limit handling
source/isaaclab/docs/CHANGELOG.rst 5/5 Added changelog entry documenting the effort limit bug fix for version 0.47.8

Sequence Diagram

sequenceDiagram
    participant Articulation
    participant USD Asset
    participant ActuatorBase
    participant PhysX Solver

    Note over Articulation: Initialize actuator groups
    Articulation->>USD Asset: Read joint_effort_limits
    USD Asset-->>Articulation: Return effort_limit tensor (e.g., 80.0)
    
    Note over Articulation: Pass effort_limit to actuator
    Articulation->>Articulation: Clone effort_limit tensor
    Articulation->>ActuatorBase: __init__(effort_limit=cloned_tensor)
    
    Note over ActuatorBase: Check cfg.effort_limit
    alt cfg.effort_limit is None
        ActuatorBase->>ActuatorBase: Use USD value (effort_limit param)
        Note over ActuatorBase: effort_default = effort_limit
    else cfg.effort_limit is specified
        ActuatorBase->>ActuatorBase: Use effort_limit_sim
        Note over ActuatorBase: effort_default = effort_limit_sim
    end
    
    ActuatorBase->>ActuatorBase: _parse_joint_parameter(cfg.effort_limit, effort_default)
    Note over ActuatorBase: Creates independent copy<br/>of effort limits
    
    ActuatorBase->>PhysX Solver: Apply effort_limit_sim to solver
    Note over PhysX Solver: For explicit actuators:<br/>effort_limit_sim = 1.0e9<br/>(avoid double-clipping)
Loading

2 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@kellyguo11
Copy link
Contributor

source/isaaclab/test/actuators/test_ideal_pd_actuator.py seems to be failing now, do we need to update any of the test cases there?

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

Fixed actuator initialization to respect USD effort limits when not explicitly configured

Key Changes:

  • Modified ActuatorBase initialization to use USD-provided effort_limit values when cfg.effort_limit is None, instead of defaulting to 1.0e9
  • Added .clone() when passing effort limit tensor to prevent unintended reference sharing
  • Updated documentation to clarify the distinct roles of effort_limit (internal model clipping) vs effort_limit_sim (PhysX solver limit)

Impact:

  • Explicit actuator models (e.g., DC motor) now correctly use finite effort limits from USD assets for internal torque clipping
  • effort_limit_sim remains at 1.0e9 for explicit models to avoid double-clipping at the PhysX level
  • Implicit actuators are unaffected (both limits remain synchronized)

Confidence Score: 5/5

  • Safe to merge with high confidence
  • Well-designed fix with comprehensive test coverage, proper documentation, and correct handling of tensor references; addresses the reported bug without introducing side effects
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
source/isaaclab/isaaclab/actuators/actuator_base.py 5/5 Correctly implements logic to use USD effort limits when cfg.effort_limit is None for explicit actuators; improved documentation
source/isaaclab/isaaclab/assets/articulation/articulation.py 5/5 Added .clone() to prevent unintended reference sharing when passing effort_limit tensor to actuator constructor
source/isaaclab/test/assets/test_articulation.py 5/5 Enhanced test coverage with additional test case (80.0) matching USD default; improved test documentation and assertions

Sequence Diagram

sequenceDiagram
    participant Articulation
    participant ActuatorBase
    participant ParseJointParam
    participant USD as USD Asset

    Note over USD: effort_limit = 80.0
    
    Articulation->>ActuatorBase: __init__(effort_limit=joint_effort_limits.clone())
    Note over Articulation: .clone() prevents reference issues
    
    alt Explicit Actuator && cfg.effort_limit_sim is None
        ActuatorBase->>ActuatorBase: cfg.effort_limit_sim = 1.0e9
    end
    
    ActuatorBase->>ParseJointParam: _parse_joint_parameter(cfg.effort_limit_sim, effort_limit)
    ParseJointParam-->>ActuatorBase: effort_limit_sim = 1.0e9
    
    alt cfg.effort_limit is None
        Note over ActuatorBase: Use USD value (effort_limit)
        ActuatorBase->>ActuatorBase: effort_default = effort_limit (80.0)
    else cfg.effort_limit is set
        Note over ActuatorBase: Use effort_limit_sim
        ActuatorBase->>ActuatorBase: effort_default = effort_limit_sim (1.0e9)
    end
    
    ActuatorBase->>ParseJointParam: _parse_joint_parameter(cfg.effort_limit, effort_default)
    ParseJointParam-->>ActuatorBase: effort_limit = 80.0 (USD default)
    
    Note over ActuatorBase: Result: effort_limit=80.0, effort_limit_sim=1.0e9
Loading

6 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Signed-off-by: Kelly Guo <kellyg@nvidia.com>
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

Fixed bug where effort_limit was incorrectly overridden with large default value (1.0e9) for explicit actuator models when not specified in configuration, even when USD assets contained meaningful effort limit values.

Key changes:

  • Modified ActuatorBase.__init__ to use USD effort_limit value when cfg.effort_limit is None (actuator_base.py:214)
  • Added .clone() to prevent unintended tensor mutation in articulation.py:1716
  • Updated documentation to clarify effort_limit vs effort_limit_sim behavior for explicit/implicit actuators
  • Enhanced test coverage with USD default value test cases (80.0) for both implicit and explicit actuators

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • Bug fix is well-isolated with clear logic, comprehensive test coverage validates all three configuration scenarios, and documentation accurately explains the behavior
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
source/isaaclab/isaaclab/actuators/actuator_base.py 5/5 Fixed effort_limit initialization to use USD values when cfg.effort_limit is None, added improved documentation
source/isaaclab/isaaclab/assets/articulation/articulation.py 5/5 Added .clone() to effort_limit tensor to prevent unintended mutation of shared data
source/isaaclab/test/assets/test_articulation.py 5/5 Enhanced tests with 80.0 parameter case and proper assertions for USD default fallback behavior

Sequence Diagram

sequenceDiagram
    participant USD as USD Asset
    participant Art as Articulation
    participant AB as ActuatorBase.__init__
    participant Parse as _parse_joint_parameter

    USD->>Art: Load joint properties<br/>(effort_limit=80.0)
    Art->>Art: Clone effort_limit tensor
    Art->>AB: Initialize actuator<br/>(effort_limit=80.0 clone)
    
    alt cfg.effort_limit is None
        Note over AB: Use USD value as default
        AB->>Parse: cfg_value=None, default=80.0
        Parse-->>AB: Return tensor with 80.0
    else cfg.effort_limit is set (e.g., 100.0)
        Note over AB: Use configured value
        AB->>Parse: cfg_value=100.0, default=effort_limit_sim
        Parse-->>AB: Return tensor with 100.0
    end
    
    Note over AB: effort_limit now correctly<br/>uses USD or config value
Loading

6 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@kellyguo11 kellyguo11 merged commit a2540cd into isaac-sim:main Nov 7, 2025
6 of 7 checks passed
@github-project-automation github-project-automation bot moved this from In review to Done in Isaac Lab Nov 7, 2025
kellyguo11 added a commit that referenced this pull request Nov 26, 2025
<!--
Thank you for your interest in sending a pull request. Please make sure
to check the contribution guidelines.

Link:
https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html

💡 Please try to keep PRs small and focused. Large PRs are harder to
review and merge.
-->

This PR fixes a bug in actuator initialization where effort limits
specified in USD assets were being incorrectly overridden with a very
large default value (1.0e9) for explicit actuator models.

Fixes # (issue)

Previously, the ActuatorBase initialization logic would unconditionally
fall back to _DEFAULT_MAX_EFFORT_SIM (1.0e9) for explicit actuator
models when effort_limit_sim was not explicitly set in the
configuration, even when the USD asset contained finite, meaningful
effort limit values.

<!-- As you go through the list, delete the ones that are not
applicable. -->

- Bug fix (non-breaking change which fixes an issue)

- [x] I have read and understood the [contribution
guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html)
- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [ ] 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

<!--
As you go through the checklist above, you can mark something as done by
putting an x character in it

For example,
- [x] I have done this task
- [ ] I have not done this task
-->

---------

Signed-off-by: Juana <yvetted@nvidia.com>
Signed-off-by: Kelly Guo <kellyg@nvidia.com>
Co-authored-by: James Tigue <166445701+jtigue-bdai@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Kelly Guo <kellyg@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

asset New asset feature or request bug Something isn't working isaac-lab Related to Isaac Lab team

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants