Spaces:
Sleeping
Sleeping
| import os | |
| os.environ["MUJOCO_GL"] = "osmesa" # or "egl" if you switch to EGL support | |
| import gradio as gr | |
| from tray_sim import run_tray_simulation | |
| import time # For unique file naming | |
| # Global counter for unique file naming | |
| run_counter = 0 | |
| def simulate_and_render( | |
| seed: int, | |
| azimuth: float = 35, | |
| elevation: float = -20, | |
| distance: float = 1.0 | |
| ): | |
| """ | |
| Runs a TraySim simulation with the specified camera parameters and renders the result. | |
| Parameters: | |
| seed (int): Random seed for simulation initialization, affects object placement and dynamics. | |
| azimuth (float, optional): Horizontal camera angle in degrees. Default is 35. | |
| elevation (float, optional): Vertical camera angle in degrees. Default is -20. | |
| distance (float, optional): Distance of the camera from the scene. Default is 1.0. | |
| Returns: | |
| str: Path to the rendered GIF file showing the simulation from the specified viewpoint. | |
| """ | |
| global run_counter | |
| run_counter += 1 | |
| unique_id = f"{seed}_{run_counter}_{int(time.time())}" # Unique identifier for this run | |
| gif_path, physics_state, json_path = run_tray_simulation( | |
| seed=seed, | |
| azimuth=azimuth, | |
| elevation=elevation, | |
| distance=distance, | |
| unique_id=unique_id # Pass unique_id to avoid file conflicts | |
| ) | |
| # Optional debug | |
| print("Physics State: ", physics_state) | |
| print("JSON Path: ", json_path) | |
| return gif_path, gif_path, physics_state, json_path | |
| # Define the custom layout using Blocks | |
| with gr.Blocks( | |
| css="""#simulation_image {min-height: 600px; min-width: 700px;}""", # Set minimum size for the image | |
| theme=gr.themes.Default() | |
| ) as iface: | |
| gr.Markdown("# TraySim Simulation Viewer") | |
| gr.Markdown("Simulates object drop on a tray using MuJoCo and shows the result as a GIF.") | |
| with gr.Row(): | |
| # Input column (30% width) | |
| with gr.Column(scale=3): # scale=3 for 30% width | |
| seed_input = gr.Number(label="Random Seed", value=0) | |
| azimuth_input = gr.Slider(minimum=0, maximum=360, label="Azimuth", value=35) | |
| elevation_input = gr.Slider(minimum=-90, maximum=90, label="Elevation", value=-20) | |
| distance_input = gr.Slider(minimum=0.2, maximum=5.0, label="Zoom (Distance)", value=2.0) | |
| submit_button = gr.Button("Run Simulation") | |
| # Output column (70% width) | |
| with gr.Column(scale=7): # scale=7 for 70% width | |
| output_image = gr.Image( | |
| type="filepath", | |
| label="Simulation", | |
| elem_id="simulation_image", # Assign an ID for CSS targeting | |
| width=700, # Set default width | |
| height=600 # Set default height | |
| ) | |
| output_file = gr.File(label="Download Simulation GIF") | |
| state_output = gr.JSON(label="Physics State") | |
| json_file = gr.File(label="Download Physics State JSON") | |
| # Connect the button to the simulation function | |
| submit_button.click( | |
| fn=simulate_and_render, | |
| inputs=[seed_input, azimuth_input, elevation_input, distance_input], | |
| outputs=[output_image, output_file, state_output, json_file] | |
| ) | |
| if __name__ == "__main__": | |
| iface.launch() |