Skip to content

Commit d149c19

Browse files
committed
refactor: review of sim state recording and replay
1 parent 6480253 commit d149c19

3 files changed

Lines changed: 27 additions & 58 deletions

File tree

python/rcs/envs/sim.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ def reset(
4646
class SimStateObservationWrapper(ActObsInfoWrapper):
4747
STATE_KEY = "sim_state"
4848
STATE_SPEC_KEY = "sim_state_spec"
49-
STATE_SIZE_KEY = "sim_state_size"
5049

5150
def __init__(self, env):
5251
super().__init__(env)
@@ -58,7 +57,6 @@ def observation(self, observation: dict[str, Any], info: dict[str, Any]) -> tupl
5857
sim_state = self.sim.get_state()
5958
observation[self.STATE_KEY] = sim_state
6059
observation[self.STATE_SPEC_KEY] = self.sim.get_state_spec()
61-
observation[self.STATE_SIZE_KEY] = sim_state.shape[0]
6260
return observation, info
6361

6462

python/rcs/sim_state_replay.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,17 @@
1919
app = typer.Typer(help="Replay recorded MuJoCo trajectories from a parquet dataset.")
2020

2121
DATASET_ARGUMENT = typer.Argument(..., exists=True, file_okay=False, dir_okay=True)
22-
ENV_ID_OPTION = typer.Option("rcs/FR3SimplePickUpSim-v0", help="Gymnasium env id used for replay.")
23-
TRAJECTORY_UUID_OPTION = typer.Option(None, help="UUID of the recorded trajectory to replay.")
24-
CAMERA_OPTION = typer.Option([], "--camera", help="Camera names to enable on the replay env.")
25-
RESOLUTION_OPTION = typer.Option((256, 256), help="Replay camera resolution as WIDTH HEIGHT.")
26-
FRAME_RATE_OPTION = typer.Option(0, help="Replay camera frame rate.")
27-
RENDER_MODE_OPTION = typer.Option("human", help="Gym render mode for the replay env.")
28-
CONTROL_MODE_OPTION = typer.Option(ControlMode.CARTESIAN_TRPY.name, help="Control mode name for env creation.")
29-
SLEEP_OPTION = typer.Option(0.0, help="Optional delay between restored states.")
30-
OUTPUT_DIR_OPTION = typer.Option(None, help="Optional directory for re-rendered RGB frames.")
31-
PREFER_DUCKDB_OPTION = typer.Option(True, help="Use duckdb for parquet loading when it is available.")
22+
23+
ENV_ID_OPTION = typer.Option(help="Gymnasium env id used for replay.")
24+
TRAJECTORY_UUID_OPTION = typer.Option(help="UUID of the recorded trajectory to replay.")
25+
CAMERA_OPTION = typer.Option("--camera", help="Camera names to enable on the replay env.")
26+
RESOLUTION_OPTION = typer.Option(help="Replay camera resolution as WIDTH HEIGHT.")
27+
FRAME_RATE_OPTION = typer.Option(help="Replay camera frame rate.")
28+
RENDER_MODE_OPTION = typer.Option(help="Gym render mode for the replay env.")
29+
CONTROL_MODE_OPTION = typer.Option(help="Control mode name for env creation.")
30+
SLEEP_OPTION = typer.Option(help="Optional delay between restored states.")
31+
OUTPUT_DIR_OPTION = typer.Option(help="Optional directory for re-rendered RGB frames.")
32+
PREFER_DUCKDB_OPTION = typer.Option(help="Use duckdb for parquet loading when it is available.")
3233

3334

3435
@dataclass(frozen=True)
@@ -193,6 +194,7 @@ def replay_trajectory(
193194
env.reset()
194195
for recorded_step in recorded_steps:
195196
restore_sim_step(env, recorded_step)
197+
env.get_wrapper_attr("sim").step(1)
196198
if output_dir is not None:
197199
save_rgb_frames(output_dir, recorded_step, collect_rgb_frames(env))
198200
if sleep_s > 0:
@@ -202,17 +204,19 @@ def replay_trajectory(
202204
@app.command()
203205
def replay(
204206
dataset: Annotated[Path, DATASET_ARGUMENT],
205-
env_id: Annotated[str, ENV_ID_OPTION],
206-
trajectory_uuid: Annotated[str | None, TRAJECTORY_UUID_OPTION],
207-
camera: Annotated[list[str], CAMERA_OPTION],
208-
resolution: Annotated[tuple[int, int], RESOLUTION_OPTION],
209-
frame_rate: Annotated[int, FRAME_RATE_OPTION],
210-
render_mode: Annotated[str, RENDER_MODE_OPTION],
211-
control_mode: Annotated[str, CONTROL_MODE_OPTION],
212-
sleep_s: Annotated[float, SLEEP_OPTION],
213-
output_dir: Annotated[Path | None, OUTPUT_DIR_OPTION],
214-
prefer_duckdb: Annotated[bool, PREFER_DUCKDB_OPTION],
207+
env_id: Annotated[str, ENV_ID_OPTION] = "rcs/FR3SimplePickUpSim-v0",
208+
trajectory_uuid: Annotated[str | None, TRAJECTORY_UUID_OPTION] = None,
209+
camera: Annotated[list[str] | None, CAMERA_OPTION] = None,
210+
resolution: Annotated[tuple[int, int], RESOLUTION_OPTION] = (256, 256),
211+
frame_rate: Annotated[int, FRAME_RATE_OPTION] = 0,
212+
render_mode: Annotated[str, RENDER_MODE_OPTION] = "human",
213+
control_mode: Annotated[str, CONTROL_MODE_OPTION] = ControlMode.CARTESIAN_TRPY.name,
214+
sleep_s: Annotated[float, SLEEP_OPTION] = 0.0,
215+
output_dir: Annotated[Path | None, OUTPUT_DIR_OPTION] = None,
216+
prefer_duckdb: Annotated[bool, PREFER_DUCKDB_OPTION] = True,
215217
):
218+
if camera is None:
219+
camera = []
216220
resolved_uuid = resolve_trajectory_uuid(dataset, trajectory_uuid, prefer_duckdb=prefer_duckdb)
217221
env = gym.make(
218222
env_id,

python/tests/test_sim_state_record_replay.py

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from __future__ import annotations
22

3-
import importlib.util
4-
import sys
53
from dataclasses import dataclass
64
from pathlib import Path
75

@@ -11,41 +9,10 @@
119
import pyarrow.dataset as ds
1210
from rcs._core.common import RobotPlatform
1311
from rcs.camera.interface import CameraFrame, DataFrame, Frame, FrameSet
12+
from rcs.envs.sim import SimStateObservationWrapper
1413
from rcs.envs.storage_wrapper import StorageWrapper
15-
16-
import rcs
17-
18-
REPO_ROOT = Path(__file__).resolve().parents[2]
19-
20-
21-
def _load_local_module(module_name: str, relative_path: str):
22-
module_path = REPO_ROOT / relative_path
23-
spec = importlib.util.spec_from_file_location(module_name, module_path)
24-
if spec is None or spec.loader is None:
25-
msg = f"Could not create an import spec for {module_name} from {module_path}."
26-
raise ImportError(msg)
27-
module = importlib.util.module_from_spec(spec)
28-
sys.modules[module_name] = module
29-
parent_name, _, child_name = module_name.rpartition(".")
30-
if parent_name:
31-
parent_module = sys.modules[parent_name]
32-
setattr(parent_module, child_name, module)
33-
spec.loader.exec_module(module)
34-
return module
35-
36-
37-
local_sim_module = _load_local_module("rcs.sim.sim", "python/rcs/sim/sim.py")
38-
rcs.sim.__dict__["Sim"] = local_sim_module.Sim
39-
_load_local_module("rcs.envs.sim", "python/rcs/envs/sim.py")
40-
_load_local_module("rcs.sim_state_replay", "python/rcs/sim_state_replay.py")
41-
42-
from rcs.envs.sim import SimStateObservationWrapper # noqa: E402
43-
from rcs.sim.sim import Sim # noqa: E402
44-
from rcs.sim_state_replay import ( # noqa: E402
45-
load_trajectory,
46-
replay_trajectory,
47-
restore_sim_step,
48-
)
14+
from rcs.sim.sim import Sim
15+
from rcs.sim_state_replay import load_trajectory, replay_trajectory, restore_sim_step
4916

5017
XML = """
5118
<mujoco>

0 commit comments

Comments
 (0)