This is to properly handle the case where the interpreter wants to exit immediately, e.g. when `mjpython --version` is run.
Currently, we call `PyGILState_Ensure` regardless of the result of `Py_InitializeFromConfig` resulting in a segfault, as in issue #2870.
PiperOrigin-RevId: 869652555
Change-Id: I3a898279eb8aa25afbaece904cfdcc4fdcc92972
Python 3.7 reaches end-of-life on 27 June 2023 (https://devguide.python.org/versions/), and future versions of MuJoCo (after 2.3.6) will no longer support it.
PiperOrigin-RevId: 543594006
Change-Id: I66a7db3dab5d08f2fc52912c43e1532080600fc8
This change also requires user scripts to explicitly synchronize changes to physics state to the viewer. The Simulate class was reconfigured so that certain UI events are handled during this sync operation, outside of the render loop on the main thread. These correspond to operations that require access to the full mjModel/mjData.
To support other, more interactive operations (e.g. camera movements), a new mjvSceneState struct is introduced which captures only the portion of the physics state required for scene re-rendering. The mjvSceneState is updated from mjModel/mjData during the viewer sync operation, and is significantly cheaper than a full mj_copyModel and mj_copyData.
Fixes https://github.com/deepmind/mujoco/issues/796
PiperOrigin-RevId: 525723636
Change-Id: Id08d0210a2c067d5afe85e2bf104f276aeddd75e
- Find Python functions in the interpreter binary itself rather than trying to find libpython.dylib, because this doesn't exist when using Conda. (https://github.com/conda-forge/python-feedstock/issues/595#issuecomment-1311275470)
- Increase the stack size of both the Python main thread and the OS main thread to 16MiB, to match what Python normally uses on macOS. (https://github.com/python/cpython/blob/3.11/configure#L11038)
- Check whether dlfcn and pthread function calls actually succeeds. Emit error messages and exit on failure rather than continuing the program (which generally leads to segfaults).
- Fix pixelated shadow in the icon.
PiperOrigin-RevId: 517390522
Change-Id: Ib91679b4baa63bac5f6b5893e634712d72161ea5
The `launch_passive` function launches the GUI viewer in a non-blocking manner, allowing the Python script or REPL to continue execution. The viewer is automatically kept up to date with any subsequent modifications to mjModel and mjData.
Note that when run inside a REPL (including IPython), `launch_passive` is functionally identical to `launch_repl`.
On Linux and Windows, this is achieved by spawning a new thread and launching the GUI there.
On macOS, this is not possible as all Cocoa API calls must be made on the "macOS main thread", which is always the first thread launched in a process and carries the `com.apple.main-thread` dispatch queue. We also cannot simply trampoline from a Python script on the main thread into the user's script on a side thread because CPython's signal handler can only be installed on the "Python main thread". Putting the user's script in a side thread means that it cannot e.g. gracefully handle SIGINT by catching a KeyboardInterrupt exception. To work around this, we ship a custom Python launcher on macOS called `mjpython`. This launcher is a native binary that spawns a pthread and initialize the Python interpreter on that thread, thus allowing "Python main thread" and "macOS main thread" to represent two distinct threads. From Python's point of view, the "macOS main thread" is a secondary thread that runs a loop that continuously empties a Queue of (mjModel, mjData) and launches a viewer.
PiperOrigin-RevId: 517167868
Change-Id: Icac9d2126bbb4760d47e0b9300e0a979cffa4338