google-deepmind / mujoco

Multi-Joint dynamics with Contact. A general purpose physics simulator.
https://mujoco.org
Apache License 2.0
8.18k stars 817 forks source link

Issue with Real-time Visualization Update in MuJoCo Python API #1587

Closed kankanzheli closed 6 months ago

kankanzheli commented 7 months ago

Hi MuJoCo Team,

I'm currently developing a reinforcement learning environment using the latest MuJoCo Python API, and I've encountered an issue with the real-time visualization of the simulation. Despite following the recommended practices for rendering and updating the simulation state, the visualization window does not reflect the changes in the simulation state as expected.

Here's a brief overview of my implementation: ` def render(self, mode="none"): if mode == "human": if self.viewer is None: self.viewer = mujoco.viewer.launch_passive(self.model, self.data)

if name == "main": env.reset() done = False env.render(mode="human") while not done: action = env.action_space.sample() obs, reward, done, truncated, info = env.step(action) if done or truncated: obs = env.reset() done = False ` In the step method, I ensure that the simulation state is updated, and I call mj_step and self.viewer.sync() at the end of each step. However, the visualization window pops up but remains static and does not update according to the simulation state changes.

Here are my questions:

Are there any additional steps required to ensure that the visualization window updates in real-time with the simulation state changes? Is calling viewer.sync() after each simulation step the correct approach to update the visualization window in real-time? Could this issue be related to the specific version of the MuJoCo Python API I'm using, or is it a known issue with a workaround?

Thank you for your assistance.

Best regards

kankanzheli commented 6 months ago

I checked my code. I think this may be an error caused by my reset code. In order for mujoco to be able to load diverse environments, a new XML file is reloaded during each reset. This operation may be the reason for the visualization failure `

def merge_xmls(self, main_xml, *additional_xmls):
    main_tree = ET.parse(main_xml)
    main_root = main_tree.getroot()
    body_names = []
    main_tendon = main_root.find("tendon")
    if main_tendon is None:
        main_tendon = ET.SubElement(main_root, "tendon")
    for add_xml in additional_xmls:
        add_tree = ET.parse(add_xml)
        add_root = add_tree.getroot()
        for elem in add_root.find("worldbody"):
            main_root.find("worldbody").append(elem)
            body_names.append(elem.get('name')) 
        add_tendon = add_root.find("tendon")
        if add_tendon is not None:
            for spatial in add_tendon:
                main_tendon.append(spatial)
    self.place_random_obstacle_and_target(main_root)
    merged_path = "merged.xml"
    with open(merged_path, "wb") as f:
        f.write(ET.tostring(main_root))
    return merged_path, body_names

def reset(self, seed=None, return_info=False, options=None):
    if seed is not None:
        np.random.seed(seed)
    self.merged_xml, self.body_names = self.merge_xmls(self.robot_xml, self.ball_xml, self.box_xml)
    self.model = mujoco.MjModel.from_xml_path(self.merged_xml)
    self.data = mujoco.MjData(self.model)
    mujoco.mj_forward(self.model, self.data)
    ball_id = mujoco.mj_name2id(self.model, mujoco.mjtObj.mjOBJ_BODY, "target")
    ball_xpos = self.data.xpos[ball_id]
    #self.reset_robot_state()
    if self.viewer is not None:
        self.viewer.sync()
    self.step_count = 0
    observation = self.get_observation()   
    info = {}  
    return observation, info 

`

Is there any way to solve this problem?