Unverified Commit a52e0276 authored by Miguel Alonso Jr.'s avatar Miguel Alonso Jr. Committed by GitHub

Fixes check for manager term class inside event manager (#2357)

# Description

<!--
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
-->

In the event manager, class based event terms are not registered
properly due to a missing type() call. On [line 387
](https://github.com/isaac-sim/IsaacLab/blob/7de6d6fef9424c95fc68dc767af67ffbe0da6832/source/isaaclab/isaaclab/managers/event_manager.py#L387)of
event_manager.py, the check should be

            if isinstance(term_cfg.func, type(ManagerTermBase)):
otherwise, isinstance always returns false (since ManagerTermBase is an
abstract base class, the isintance method will check that term_cfg.func
is derived from ABC, and not ManagerTermBase). Adding
type(ManagerTermBase) resolves the issue.

Fixes https://github.com/isaac-sim/IsaacLab/issues/2342

<!-- As a practice, it is recommended to open an issue to have
discussions on the proposed pull request.
This makes it easier for the community to keep track of what is being
developed or added, and if a given feature
is demanded by more than one party. -->

## Type of change

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

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

## Screenshots

Please attach before and after screenshots of the change if applicable.

<!--
Example:

| Before | After |
| ------ | ----- |
| _gif/png before_ | _gif/png after_ |

To upload images to a PR -- simply drag and drop an image while in edit
mode and it should upload the image directly. You can then paste that
source into the above before/after sections.
-->

## Checklist

- [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: 's avatarMiguel Alonso Jr. <76960110+miguelalonsojr@users.noreply.github.com>
Signed-off-by: 's avatarKelly Guo <kellyguo123@hotmail.com>
Co-authored-by: 's avatarMiguel Alonso Jr. <miguel.alonso@nfinite.app>
Co-authored-by: 's avatarMayank Mittal <12863862+Mayankm96@users.noreply.github.com>
Co-authored-by: 's avatarKelly Guo <kellyguo123@hotmail.com>
parent 8d72e872
...@@ -79,6 +79,7 @@ Guidelines for modifications: ...@@ -79,6 +79,7 @@ Guidelines for modifications:
* Masoud Moghani * Masoud Moghani
* Michael Gussert * Michael Gussert
* Michael Noseworthy * Michael Noseworthy
* Miguel Alonso Jr
* Muhong Guo * Muhong Guo
* Nicola Loi * Nicola Loi
* Nuoyan Chen (Alvin) * Nuoyan Chen (Alvin)
......
[package] [package]
# Note: Semantic Versioning is used: https://semver.org/ # Note: Semantic Versioning is used: https://semver.org/
version = "0.36.21" version = "0.36.22"
# Description # Description
title = "Isaac Lab framework for Robot Learning" title = "Isaac Lab framework for Robot Learning"
......
Changelog Changelog
--------- ---------
0.36.22 (2025-04-23)
~~~~~~~~~~~~~~~~~~~~
Fixed
^^^^^^^
* Adds correct type check for ManagerTermBase class in event_manager.py.
0.36.21 (2025-04-15) 0.36.21 (2025-04-15)
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
......
...@@ -15,7 +15,7 @@ from typing import TYPE_CHECKING ...@@ -15,7 +15,7 @@ from typing import TYPE_CHECKING
import omni.log import omni.log
from .manager_base import ManagerBase, ManagerTermBase from .manager_base import ManagerBase
from .manager_term_cfg import EventTermCfg from .manager_term_cfg import EventTermCfg
if TYPE_CHECKING: if TYPE_CHECKING:
...@@ -134,7 +134,7 @@ class EventManager(ManagerBase): ...@@ -134,7 +134,7 @@ class EventManager(ManagerBase):
# if we are doing interval based events then we need to reset the time left # if we are doing interval based events then we need to reset the time left
# when the episode starts. otherwise the counter will start from the last time # when the episode starts. otherwise the counter will start from the last time
# for that environment # for that environment
if "interval" in self._mode_class_term_cfgs: if "interval" in self._mode_term_cfgs:
for index, term_cfg in enumerate(self._mode_class_term_cfgs["interval"]): for index, term_cfg in enumerate(self._mode_class_term_cfgs["interval"]):
# sample a new interval and set that as time left # sample a new interval and set that as time left
# note: global time events are based on simulation time and not episode time # note: global time events are based on simulation time and not episode time
...@@ -384,7 +384,7 @@ class EventManager(ManagerBase): ...@@ -384,7 +384,7 @@ class EventManager(ManagerBase):
self._mode_term_cfgs[term_cfg.mode].append(term_cfg) self._mode_term_cfgs[term_cfg.mode].append(term_cfg)
# check if the term is a class # check if the term is a class
if isinstance(term_cfg.func, ManagerTermBase): if inspect.isclass(term_cfg.func):
self._mode_class_term_cfgs[term_cfg.mode].append(term_cfg) self._mode_class_term_cfgs[term_cfg.mode].append(term_cfg)
# resolve the mode of the events # resolve the mode of the events
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
# pyright: reportPrivateUsage=none # pyright: reportPrivateUsage=none
"""Launch Isaac Sim Simulator first.""" """Launch Isaac Sim Simulator first."""
from collections.abc import Sequence
from isaaclab.app import AppLauncher, run_tests from isaaclab.app import AppLauncher, run_tests
...@@ -19,7 +20,8 @@ import torch ...@@ -19,7 +20,8 @@ import torch
import unittest import unittest
from collections import namedtuple from collections import namedtuple
from isaaclab.managers import EventManager, EventTermCfg from isaaclab.envs import ManagerBasedEnv
from isaaclab.managers import EventManager, EventTermCfg, ManagerTermBase, ManagerTermBaseCfg
from isaaclab.sim import SimulationContext from isaaclab.sim import SimulationContext
from isaaclab.utils import configclass from isaaclab.utils import configclass
...@@ -47,6 +49,36 @@ def increment_dummy2_by_one(env, env_ids: torch.Tensor): ...@@ -47,6 +49,36 @@ def increment_dummy2_by_one(env, env_ids: torch.Tensor):
env.dummy2[env_ids] += 1 env.dummy2[env_ids] += 1
class reset_dummy2_to_zero_class(ManagerTermBase):
def __init__(self, cfg: ManagerTermBaseCfg, env: ManagerBasedEnv):
super().__init__(cfg, env)
def reset(self, env_ids: Sequence[int] | None = None) -> None:
pass
def __call__(
self,
env: ManagerBasedEnv,
env_ids: torch.Tensor,
) -> None:
env.dummy2[env_ids] = 0
class increment_dummy2_by_one_class(ManagerTermBase):
def __init__(self, cfg: ManagerTermBaseCfg, env: ManagerBasedEnv):
super().__init__(cfg, env)
def reset(self, env_ids: Sequence[int] | None = None) -> None:
pass
def __call__(
self,
env: ManagerBasedEnv,
env_ids: torch.Tensor,
) -> None:
env.dummy2[env_ids] += 1
class TestEventManager(unittest.TestCase): class TestEventManager(unittest.TestCase):
"""Test cases for various situations with event manager.""" """Test cases for various situations with event manager."""
...@@ -137,6 +169,21 @@ class TestEventManager(unittest.TestCase): ...@@ -137,6 +169,21 @@ class TestEventManager(unittest.TestCase):
self.assertEqual(len(self.event_man.active_terms["reset"]), 1) self.assertEqual(len(self.event_man.active_terms["reset"]), 1)
self.assertEqual(len(self.event_man.active_terms["custom"]), 2) self.assertEqual(len(self.event_man.active_terms["custom"]), 2)
def test_class_terms(self):
"""Test the correct preparation of function and class event terms."""
cfg = {
"term_1": EventTermCfg(func=reset_dummy2_to_zero, mode="reset"),
"term_2": EventTermCfg(func=increment_dummy2_by_one_class, mode="interval", interval_range_s=(0.1, 0.1)),
"term_3": EventTermCfg(func=reset_dummy2_to_zero_class, mode="reset"),
}
self.event_man = EventManager(cfg, self.env)
self.assertEqual(len(self.event_man.active_terms), 2)
self.assertEqual(len(self.event_man.active_terms["interval"]), 1)
self.assertEqual(len(self.event_man.active_terms["reset"]), 2)
self.assertEqual(len(self.event_man._mode_class_term_cfgs), 2)
self.assertEqual(len(self.event_man._mode_class_term_cfgs["reset"]), 1)
def test_config_empty(self): def test_config_empty(self):
"""Test the creation of reward manager with empty config.""" """Test the creation of reward manager with empty config."""
self.event_man = EventManager(None, self.env) self.event_man = EventManager(None, self.env)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment