-
Notifications
You must be signed in to change notification settings - Fork 11
bowl and microwave env #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
0310dae
42d5e8a
26fbc52
11e7b7e
9c8ba63
bf74810
662cfa7
3a88122
39cd96c
b076bf5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| #!/usr/bin/env python3 | ||
| """ | ||
| Teleop script for Hang Lifebuoy environment. | ||
| """ | ||
|
|
||
| import genesis as gs | ||
| import torch | ||
| from gs_agent.wrappers.teleop_wrapper import KeyboardWrapper | ||
| from gs_env.sim.envs.config.registry import EnvArgsRegistry | ||
| from gs_env.sim.envs.manipulation.hang_lifebuoy_env import HangLifebuoyEnv | ||
|
|
||
|
|
||
| def main() -> None: | ||
| """Run teleop for hang lifebuoy task.""" | ||
| print("Initializing Hang Lifebuoy Teleop System...") | ||
|
|
||
| # Initialize Genesis | ||
| gs.init( | ||
| seed=0, | ||
| precision="32", | ||
| logging_level="info", | ||
| backend=gs.cpu, # type: ignore | ||
| ) | ||
|
|
||
| # Create teleop wrapper first (without environment) | ||
| print("Creating teleop wrapper...") | ||
| teleop_wrapper = KeyboardWrapper( | ||
| env=None, | ||
| device=torch.device("cpu"), | ||
| movement_speed=0.01, # Position movement speed | ||
| rotation_speed=0.05, # Rotation speed | ||
| trajectory_filename_prefix="hang_lifebuoy_", | ||
| ) | ||
|
|
||
| # Start teleop wrapper (keyboard listener) FIRST, before creating Genesis scene | ||
| teleop_wrapper.start() # type: ignore | ||
|
||
|
|
||
| # Create task environment AFTER teleop wrapper is running | ||
| env = HangLifebuoyEnv( | ||
| args=EnvArgsRegistry["hang_lifebuoy_default"], | ||
| device=torch.device("cpu"), | ||
| ) | ||
| teleop_wrapper.set_environment(env) | ||
|
|
||
| print("\n" + "=" * 50) | ||
| print("Hang Lifebuoy TELEOP SYSTEM READY") | ||
| print("=" * 50) | ||
| print("📝 TRAJECTORY RECORDING INSTRUCTIONS:") | ||
| print(" 1. Press 'r' to start recording (anytime)") | ||
| print(" 2. Move robot with arrow keys, n/m, space") | ||
| print(" 3. Press 'r' again to stop recording and save") | ||
| print(" 💡 Recording works from any state now!") | ||
| print("=" * 50) | ||
|
|
||
| # Run the main control loop in the main thread (Genesis viewer requires this) | ||
| try: | ||
| step_count = 0 | ||
| while teleop_wrapper.running: | ||
| # Step the teleop wrapper (this processes input and steps environment) | ||
| teleop_wrapper.step(torch.tensor([])) | ||
| step_count += 1 | ||
|
|
||
| # Check for quit command | ||
| if ( | ||
| hasattr(teleop_wrapper, "last_command") | ||
| and teleop_wrapper.last_command | ||
| and hasattr(teleop_wrapper.last_command, "quit_teleop") | ||
| and teleop_wrapper.last_command.quit_teleop | ||
| ): | ||
| print("Quit command received, exiting...") | ||
| break | ||
|
|
||
| # Safety check - exit after 1 hour of running | ||
| if step_count > 180000: # 1 hour at 50Hz | ||
| print("Maximum runtime reached, exiting...") | ||
| break | ||
|
|
||
| except KeyboardInterrupt: | ||
| print("\n👋 Teleop interrupted by user") | ||
|
|
||
| finally: | ||
| # Cleanup | ||
| teleop_wrapper.stop() | ||
| print("✅ Teleop session ended") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| #!/usr/bin/env python3 | ||
| """ | ||
| Teleop script for Put Bowl Inside Microwave environment. | ||
| """ | ||
|
|
||
| import genesis as gs | ||
| import torch | ||
| from gs_agent.wrappers.teleop_wrapper import KeyboardWrapper | ||
| from gs_env.sim.envs.config.registry import EnvArgsRegistry | ||
| from gs_env.sim.envs.manipulation.put_bowl_inside_microwave_env import PutBowlInsideMicrowaveEnv | ||
|
|
||
|
|
||
| def main() -> None: | ||
| """Run teleop for put bowl inside microwave task.""" | ||
| print("Initializing Put Bowl Inside Microwave Teleop System...") | ||
|
|
||
| # Initialize Genesis | ||
| gs.init( | ||
| seed=0, | ||
| precision="32", | ||
| logging_level="info", | ||
| backend=gs.cpu, # type: ignore | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same |
||
| ) | ||
|
|
||
| # Create teleop wrapper first (without environment) | ||
| print("Creating teleop wrapper...") | ||
| teleop_wrapper = KeyboardWrapper( | ||
| env=None, | ||
| device=torch.device("cpu"), | ||
| movement_speed=0.01, # Position movement speed | ||
| rotation_speed=0.05, # Rotation speed | ||
| trajectory_filename_prefix="put_bowl_microwave_", | ||
| ) | ||
|
|
||
| # Start teleop wrapper (keyboard listener) FIRST, before creating Genesis scene | ||
| teleop_wrapper.start() # type: ignore | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also here. |
||
|
|
||
| # Create task environment AFTER teleop wrapper is running | ||
| env = PutBowlInsideMicrowaveEnv( | ||
| args=EnvArgsRegistry["put_bowl_inside_microwave_default"], | ||
| device=torch.device("cpu"), | ||
| ) | ||
| teleop_wrapper.set_environment(env) | ||
|
|
||
| print("\n" + "=" * 50) | ||
| print("Put Bowl Inside Microwave TELEOP SYSTEM READY") | ||
| print("=" * 50) | ||
| print("📝 TRAJECTORY RECORDING INSTRUCTIONS:") | ||
| print(" 1. Press 'r' to start recording (anytime)") | ||
| print(" 2. Move robot with arrow keys, n/m, space") | ||
| print(" 3. Press 'r' again to stop recording and save") | ||
| print(" 💡 Recording works from any state now!") | ||
| print("=" * 50) | ||
|
|
||
| # Run the main control loop in the main thread (Genesis viewer requires this) | ||
| try: | ||
| step_count = 0 | ||
| while teleop_wrapper.running: | ||
| # Step the teleop wrapper (this processes input and steps environment) | ||
| teleop_wrapper.step(torch.tensor([])) | ||
| step_count += 1 | ||
|
|
||
| # Check for quit command | ||
| if ( | ||
| hasattr(teleop_wrapper, "last_command") | ||
| and teleop_wrapper.last_command | ||
| and hasattr(teleop_wrapper.last_command, "quit_teleop") | ||
| and teleop_wrapper.last_command.quit_teleop | ||
| ): | ||
| print("Quit command received, exiting...") | ||
| break | ||
|
|
||
| # Safety check - exit after 1 hour of running | ||
| if step_count > 180000: # 1 hour at 50Hz | ||
| print("Maximum runtime reached, exiting...") | ||
| break | ||
|
|
||
| except KeyboardInterrupt: | ||
| print("\n👋 Teleop interrupted by user") | ||
|
|
||
| finally: | ||
| # Cleanup | ||
| teleop_wrapper.stop() | ||
| print("✅ Teleop session ended") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| #!/usr/bin/env python3 | ||
| """ | ||
| Teleop script for Sweep Table environment. | ||
| """ | ||
|
|
||
| import genesis as gs | ||
| import torch | ||
| from gs_agent.wrappers.teleop_wrapper import KeyboardWrapper | ||
| from gs_env.sim.envs.config.registry import EnvArgsRegistry | ||
| from gs_env.sim.envs.manipulation.sweep_table_env import SweepTableEnv | ||
|
|
||
|
|
||
| def main() -> None: | ||
| """Run teleop for sweep table task.""" | ||
| print("Initializing Sweep Table Teleop System...") | ||
|
|
||
| # Initialize Genesis | ||
| gs.init( | ||
| seed=0, | ||
| precision="32", | ||
| logging_level="info", | ||
| backend=gs.cpu, # type: ignore | ||
|
||
| ) | ||
|
|
||
| # Create teleop wrapper first (without environment) | ||
| print("Creating teleop wrapper...") | ||
| teleop_wrapper = KeyboardWrapper( | ||
| env=None, | ||
| device=torch.device("cpu"), | ||
| movement_speed=0.01, # Position movement speed | ||
| rotation_speed=0.05, # Rotation speed | ||
| trajectory_filename_prefix="sweep_table_", | ||
| ) | ||
|
|
||
| # Start teleop wrapper (keyboard listener) FIRST, before creating Genesis scene | ||
| teleop_wrapper.start() # type: ignore | ||
|
||
|
|
||
| # Create task environment AFTER teleop wrapper is running | ||
| env = SweepTableEnv( | ||
| args=EnvArgsRegistry["sweep_table_default"], | ||
| device=torch.device("cpu"), | ||
| ) | ||
| teleop_wrapper.set_environment(env) | ||
|
|
||
| print("\n" + "=" * 50) | ||
| print("Sweep Table TELEOP SYSTEM READY") | ||
| print("=" * 50) | ||
| print("📝 TRAJECTORY RECORDING INSTRUCTIONS:") | ||
| print(" 1. Press 'r' to start recording (anytime)") | ||
| print(" 2. Move robot with arrow keys, n/m, space") | ||
| print(" 3. Press 'r' again to stop recording and save") | ||
| print(" 💡 Recording works from any state now!") | ||
| print("=" * 50) | ||
|
|
||
| # Run the main control loop in the main thread (Genesis viewer requires this) | ||
| try: | ||
| step_count = 0 | ||
| while teleop_wrapper.running: | ||
| # Step the teleop wrapper (this processes input and steps environment) | ||
| teleop_wrapper.step(torch.tensor([])) | ||
| step_count += 1 | ||
|
|
||
| # Check for quit command | ||
| if ( | ||
| hasattr(teleop_wrapper, "last_command") | ||
| and teleop_wrapper.last_command | ||
| and hasattr(teleop_wrapper.last_command, "quit_teleop") | ||
| and teleop_wrapper.last_command.quit_teleop | ||
| ): | ||
| print("Quit command received, exiting...") | ||
| break | ||
|
|
||
| # Safety check - exit after 1 hour of running | ||
| if step_count > 180000: # 1 hour at 50Hz | ||
| print("Maximum runtime reached, exiting...") | ||
| break | ||
|
|
||
| except KeyboardInterrupt: | ||
| print("\n👋 Teleop interrupted by user") | ||
|
|
||
| finally: | ||
| # Cleanup | ||
| teleop_wrapper.stop() | ||
| print("✅ Teleop session ended") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -207,22 +207,27 @@ def get_observations(self) -> torch.Tensor: | |
|
|
||
| def _convert_observation_to_dict(self) -> dict[str, Any]: | ||
| """Convert tensor observation to dictionary format for teleop compatibility.""" | ||
|
|
||
| # Get cube position | ||
| cube_pos = np.array(self._env.entities["cube"].get_pos()) | ||
| cube_quat = np.array(self._env.entities["cube"].get_quat()) | ||
|
|
||
| # Create observation dictionary (for teleop compatibility) | ||
| observation = { | ||
| "ee_pose": self._env.entities["robot"].ee_pose, | ||
| # "end_effector_pos": robot_obs["end_effector_pos"], | ||
| # "end_effector_quat": robot_obs["end_effector_quat"], | ||
| "cube_pos": cube_pos, | ||
| "cube_quat": cube_quat, | ||
| "rgb_images": {}, # No cameras in this simple setup | ||
| "depth_images": {}, # No depth sensors in this simple setup | ||
| } | ||
|
|
||
| # Add all object positions dynamically (excluding robot, plane, table, ee_frame) | ||
| excluded_entities = {"robot", "plane", "table", "ee_frame"} | ||
| for entity_name, entity in self._env.entities.items(): | ||
| if entity_name not in excluded_entities: | ||
| try: | ||
| obj_pos = np.array(entity.get_pos()) | ||
| obj_quat = np.array(entity.get_quat()) | ||
| observation[f"{entity_name}_pos"] = obj_pos | ||
| observation[f"{entity_name}_quat"] = obj_quat | ||
| except Exception as e: | ||
| # Skip entities that don't have get_pos/get_quat methods | ||
| print(f"Warning: Could not get pose for entity '{entity_name}': {e}") | ||
| continue | ||
|
||
|
|
||
| return observation | ||
|
|
||
| def _process_input(self) -> KeyboardCommand: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| from .manipulation import GoalReachingEnv, HangLifebuoyEnv, PutBowlInsideMicrowaveEnv, SweepTableEnv | ||
|
|
||
| __all__ = [ | ||
| "GoalReachingEnv", | ||
| "HangLifebuoyEnv", | ||
| "PutBowlInsideMicrowaveEnv", | ||
| "SweepTableEnv", | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also pick_cube_env |
||
| ] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,11 @@ | ||
| from .goal_reaching_env import GoalReachingEnv | ||
| from .hang_lifebuoy_env import HangLifebuoyEnv | ||
| from .put_bowl_inside_microwave_env import PutBowlInsideMicrowaveEnv | ||
| from .sweep_table_env import SweepTableEnv | ||
|
|
||
| __all__ = [ | ||
| "GoalReachingEnv", | ||
| "HangLifebuoyEnv", | ||
| "PutBowlInsideMicrowaveEnv", | ||
| "SweepTableEnv", | ||
| ] |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i am not sure if we need
type: ignoreit here.