Skip to content

Commit 9a2146d

Browse files
committed
fix(isaac): mirror real SimEngine abstract surface in fallback ABC
cagataycali's review comment on simulation.py:50 (#47) flagged that the fallback ABC declared zero @AbstractMethod decorators, so IsaacSimulation() instantiated cleanly in tests when strands-robots was absent — masking the abstract-method gap that surfaces the moment the real ABC is in scope. Mirror the real strands_robots.simulation.base.SimEngine surface (14 abstract methods) in the fallback. Now `pytest` produces the same failure mode (25 failed / 33 passed) whether strands-robots is installed or not, including the dedicated canary test_isaac_implements_all_abstract_methods. The 4 missing concrete implementations on IsaacSimulation (list_robots, remove_robot, remove_object, robot_joint_names) remain a separately tracked gap per the PR body — this commit just makes the gap visible in CI.
1 parent c63cde6 commit 9a2146d

1 file changed

Lines changed: 37 additions & 2 deletions

File tree

strands_robots_sim/isaac/simulation.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,45 @@
3636
except (ImportError, ModuleNotFoundError):
3737
# Fallback: strands-robots < 0.4.0 doesn't have simulation.base yet.
3838
# Provide a minimal ABC stub so the class can still be defined.
39-
from abc import ABC
39+
from abc import ABC, abstractmethod
4040

4141
class SimEngine(ABC): # type: ignore[no-redef]
42-
"""Minimal fallback ABC when strands-robots.simulation.base is unavailable."""
42+
"""Minimal fallback ABC when strands-robots.simulation.base is unavailable.
43+
44+
Mirrors the abstract surface of the real
45+
``strands_robots.simulation.base.SimEngine`` so subclasses fail fast at
46+
instantiation if a method is missing -- same contract whether
47+
``strands_robots`` is installed or not.
48+
"""
49+
50+
@abstractmethod
51+
def create_world(self, **kwargs): ...
52+
@abstractmethod
53+
def destroy(self): ...
54+
@abstractmethod
55+
def reset(self): ...
56+
@abstractmethod
57+
def step(self, n_steps: int = 1): ...
58+
@abstractmethod
59+
def get_state(self): ...
60+
@abstractmethod
61+
def add_robot(self, name: str, **kwargs): ...
62+
@abstractmethod
63+
def remove_robot(self, name: str): ...
64+
@abstractmethod
65+
def list_robots(self) -> list: ...
66+
@abstractmethod
67+
def robot_joint_names(self, robot_name: str) -> list: ...
68+
@abstractmethod
69+
def add_object(self, name: str, **kwargs): ...
70+
@abstractmethod
71+
def remove_object(self, name: str): ...
72+
@abstractmethod
73+
def get_observation(self, robot_name=None, *, skip_images=False): ...
74+
@abstractmethod
75+
def send_action(self, action, robot_name=None, n_substeps: int = 1): ...
76+
@abstractmethod
77+
def render(self, camera_name: str = "default", width=None, height=None): ...
4378

4479
def cleanup(self) -> None:
4580
pass

0 commit comments

Comments
 (0)