Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions source/isaaclab/changelog.d/core-test-direct-marl.skip
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Test-only change
70 changes: 18 additions & 52 deletions source/isaaclab/test/envs/test_direct_marl_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,62 +20,28 @@
import pytest

import isaaclab.sim as sim_utils
from isaaclab.envs import DirectMARLEnv, DirectMARLEnvCfg
from isaaclab.scene import InteractiveSceneCfg
from isaaclab.utils.configclass import configclass
from isaaclab.envs import DirectMARLEnv
from isaaclab.test.env_cfgs import make_empty_direct_marl_env_cfg

pytestmark = pytest.mark.integration


@configclass
class EmptySceneCfg(InteractiveSceneCfg):
"""Configuration for an empty scene."""

pass


def get_empty_base_env_cfg(device: str = "cuda:0", num_envs: int = 1, env_spacing: float = 1.0):
"""Generate base environment config based on device"""

@configclass
class EmptyEnvCfg(DirectMARLEnvCfg):
"""Configuration for the empty test environment."""

# Scene settings
scene: EmptySceneCfg = EmptySceneCfg(num_envs=num_envs, env_spacing=env_spacing)
# Basic settings
decimation = 1
possible_agents = ["agent_0", "agent_1"]
action_spaces = {"agent_0": 1, "agent_1": 2}
observation_spaces = {"agent_0": 3, "agent_1": 4}
state_space = -1
episode_length_s = 100.0

return EmptyEnvCfg()


@pytest.mark.parametrize("device", ["cuda:0", "cpu"])
def test_initialization(device):
"""Test initialization of DirectMARLEnv."""
# create a new stage
def test_initialization_and_close(device):
"""DirectMARLEnv initializes its spaces and releases its simulation context."""
sim_utils.create_new_stage()
try:
# create environment
env = DirectMARLEnv(cfg=get_empty_base_env_cfg(device=device))
except Exception as e:
if "env" in locals() and hasattr(env, "_is_closed"):
env.close()
else:
if hasattr(e, "obj") and hasattr(e.obj, "_is_closed"):
e.obj.close()
pytest.fail(f"Failed to set-up the DirectMARLEnv environment. Error: {e}")
env = DirectMARLEnv(cfg=make_empty_direct_marl_env_cfg(device=device))

# check multi-agent config
assert env.num_agents == 2
assert env.max_num_agents == 2
# check spaces
assert env.state_space.shape == (7,)
assert len(env.observation_spaces) == 2
assert len(env.action_spaces) == 2
# close the environment
env.close()
try:
assert not env._is_closed
assert sim_utils.SimulationContext.instance() is env.sim
assert env.num_agents == 2
assert env.max_num_agents == 2
assert len(env.observation_spaces) == 2
assert len(env.action_spaces) == 2
assert env.state_space.shape == (7,)
finally:
env.close()
Comment thread
nvsekkin marked this conversation as resolved.

assert env._is_closed
assert sim_utils.SimulationContext.instance() is None
47 changes: 47 additions & 0 deletions source/isaaclab/test/envs/test_direct_marl_env_spaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause

# ignore private usage of variables warning
# pyright: reportPrivateUsage=none

"""Unit tests for direct multi-agent environment space construction."""

from __future__ import annotations

from types import SimpleNamespace

import gymnasium as gym
import pytest

from isaaclab.envs import DirectMARLEnv
from isaaclab.test.env_cfgs import make_empty_direct_marl_env_cfg

pytestmark = pytest.mark.unit


def test_agent_and_space_configuration():
"""Agent counts and spaces are configured without initializing the simulator."""
env = object.__new__(DirectMARLEnv)
env._is_closed = True
env.cfg = make_empty_direct_marl_env_cfg(device="cpu")
env.scene = SimpleNamespace(num_envs=env.cfg.scene.num_envs)
env.sim = SimpleNamespace(device=env.cfg.sim.device)

env._configure_env_spaces()
Comment thread
nvsekkin marked this conversation as resolved.
Outdated

assert env.agents == ["agent_0", "agent_1"]
assert env.possible_agents == ["agent_0", "agent_1"]
assert env.num_agents == 2
assert env.max_num_agents == 2
assert len(env.observation_spaces) == 2
assert len(env.action_spaces) == 2
assert all(isinstance(space, gym.spaces.Box) for space in env.observation_spaces.values())
assert all(isinstance(space, gym.spaces.Box) for space in env.action_spaces.values())
assert env.observation_spaces["agent_0"].shape == (3,)
assert env.observation_spaces["agent_1"].shape == (4,)
assert env.action_spaces["agent_0"].shape == (1,)
assert env.action_spaces["agent_1"].shape == (2,)
assert isinstance(env.state_space, gym.spaces.Box)
assert env.state_space.shape == (7,)
Loading