Skip to content

Cleaning up exits - #176

Merged
vikashplus merged 4 commits into
devfrom
cleaner_exits
Aug 9, 2026
Merged

vikashplus merged 4 commits into
devfrom
cleaner_exits

Conversation

@vikashplus

Copy link
Copy Markdown
Owner

Can you check it once on hardware as well before approving.

…ng hardware connections

- env_base.py: close() now also closes robot (hardware) and sim_obsd (when it
  differs from sim), instead of only closing sim. Added close_hardware=True arg
  so callers can leave a hardware connection open across close()/make() cycles
  intentionally (env.close(close_hardware=False)). Added a warn-only __del__,
  mirroring Robot's, so a hardware-backed env that's GC'd without close() ever
  being called surfaces a RuntimeWarning instead of silently dangling.
- robot.py: Robot.__init__ was assigning the persistent session via
  self.robot_config, which only ever shadowed the class attribute on that one
  instance and silently defeated reuse across separate Robot()/env.make() calls.
  Now assigns via type(self).robot_config so the session is genuinely shared.
  Robot.close() gained the matching close_hardware arg, and tracks
  _explicitly_closed so __del__ doesn't false-positive when hardware was left
…uld get silently swallowed

- renderer.py/mj_renderer.py: replaced the private MJRenderer._user_exit flag with
  a base-class Renderer.exit_requested property so any backend can surface it.
  Also set it when the viewer window's native close ('X') button is used, not just
  Escape, which previously did nothing.
- env_base.py: added MujocoEnv.viewer_exit_requested. examine_policy()/
  examine_policy_new() now check it in their rollout while-loop (and again to break
  the outer episode loop), instead of continuing to step invisibly after the window
  closes. For offscreen/none rendering, which has no window at all, both loops now
  catch KeyboardInterrupt and stop the same way, returning whatever was completed.
  Offscreen video writes are trimmed to the frames actually rendered before an
  early stop instead of writing out the pre-allocated zero-filled tail.
- mj_sim_scene.py: SimScene.advance() had a bare , which also swallows
  KeyboardInterrupt/SystemExit, not just real errors. That meant a Ctrl+C landing
  inside sim.step() got eaten and turned into a silent physics reset instead of
  reaching the new rollout-loop handler. Narrowed to dm_control's PhysicsError and
  included the underlying exception in the warning message
@vikashplus
vikashplus requested a review from andreh1111 August 5, 2026 23:17
…efault Robot class

Yesterday's change to persist robot_config on the class (so a hardware
session survives an env.close()/make() cycle) also applied to sim-only
robots, which all default to the same Robot class. Creating one sim env
after another in the same process left the second one silently reusing
the first's sensor/actuator config -- e.g. test_arms.py would crash with
an IndexError once a larger model's config leaked into a smaller model's
sim.data.sensordata.

- robot.py: scope the class-level persistence to is_hardware sessions
  only; sim sessions get a per-instance robot_config that can't leak.
  close() now also clears whichever level actually holds the config
  (class attr for hardware, instance attr for sim) instead of only ever
  touching the class attr.
- test_envs.py: check_env/check_old_envs now call env.close() instead of
  relying on GC via del(), exercising the real teardown path.
@vikashplus
vikashplus requested a review from andreh1111 August 6, 2026 16:43
@vikashplus
vikashplus merged commit d3540f1 into dev Aug 9, 2026
1 of 3 checks passed
@vikashplus
vikashplus deleted the cleaner_exits branch August 9, 2026 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants