Introduce a new header `gil.h` defining `MutexLockIfGilDisabled` to support thread-safety in both standard and free-threaded CPython builds.
Protect critical shared states and registries:
- Guard global Python callback pointers in `callbacks.cc` using a mutex. Move `gil_scoped_acquire` into local blocks around refcount modifications to prevent `longjmp` from bypassing destructors.
- Protect raw pointer maps in `structs_wrappers.cc` with static mutexes.
- Replace TOCTOU race in `mjcb_time` initialization with thread-safe `std::call_once`.
- Add synchronization to lazy indexer array cache initialization in `indexers.cc` and `indexer_xmacro.h`.
- Protect vector mutations in `StructListBase::PopulateUpTo` in `structs.h` with a mutex.
- Revert unnecessary atomic changes to threadpool counters.
- Declare free-threading compatibility by passing `pybind11::mod_gil_not_used()` to all extension modules.
Fixes#3259Fixes#3256Fixes#2978
PiperOrigin-RevId: 941101502
Change-Id: Iec4ce58afcbc75d4b0be6a9a21fc8a47854242e3
- `sim_app.py` provides a SimEventHook and a Handle class for the simulation process to interact with the viewer, including sending state snapshots and processing viewer events.
- `viewer_app.py` implements the main viewer application logic, handling user input, building the Dear ImGui GUI, and managing communication with the simulation process. It also includes hooks for custom viewer behavior.
PiperOrigin-RevId: 940994701
Change-Id: I82786872cd885b15454843b3a4d1160ff0b4be2b
The ViewerEndpoint can now send Snapshot messages to the SimEndpoint. The SimEndpoint has a new method, `get_viewer_snapshots`, to retrieve these. Thsi channel will be used for UI state needed for the simulation (e.g., `MjOption` and `StepControl`).
PiperOrigin-RevId: 940981799
Change-Id: Ib9bd6ad848cd5479bc49492a34fddd82569cb09f
StepControl methods SetSpeed, SetNoiseParameters, and SetPauseState now return a boolean indicating whether the state was actually changed. The GUI functions NoiseGui and StepControlGui also return a boolean reflecting if any parameters were modified. Noise parameters are now directly managed by StepControl rather than being stored in UxState. The StepControlEvent message has been expanded to include all step control parameters. Keyboard event handling has been slightly refactored to better align with event-based updates.
PiperOrigin-RevId: 940656342
Change-Id: I3701623a2fdcfc4c084b5db0ae19048669040de4
- `messages.py`: Defines base classes for `Message`, `Snapshot`, and `Event`, along with `SnapshotChannel` and `EventChannel` protocols. It also includes concrete message types for state, reset, model, perturbation, pause state, and exit events.
- `endpoints.py`: Provides `ViewerEndpoint` and `SimEndpoint` classes to manage message routing between the simulation and the viewer via the defined channels. A `make_endpoints` function is included to create both endpoints.
PiperOrigin-RevId: 939659912
Change-Id: I61a52a7d25431bc4ed38a184813882145eb421d1
Introduced a ViewerConfig dataclass to encapsulate common viewer window parameters. The NativeViewer now accepts a ViewerConfig and no longer requires a model at initialization. The Viewer protocol has been updated to include a close method (renamed from stop) and an upload_image method. Added checks for None models/data in studio event handling.
PiperOrigin-RevId: 939631378
Change-Id: Ibc07d0e775efa0d79ce5552ee52102e943a9b290
The `StepControl.advance` method now checks if the provided `model` or `data` Python objects are `None` before attempting to cast them to `MjModelWrapper` or `MjDataWrapper`, passing `nullptr` to the underlying C++ function if they are `None`.
This fixes an oversight in the python bindings, C++ code already supported null models.
PiperOrigin-RevId: 937243996
Change-Id: Ie67b8603517e7390fb54bfefbfed79ccf7b2bc5e
--
6ab68a057443f038a3d844807f205b1c99cab944 by Kevin Zakka <kevinarmandzakka@gmail.com>:
Fix pickle code-execution vulnerability in sysid loaders
Serialize signal_mapping as JSON so the trajectory and time series loaders can use allow_pickle=False, preventing arbitrary code execution from untrusted .npz files.
COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3353 from kevinzakka:sysid-disable-pickle-load 6ab68a057443f038a3d844807f205b1c99cab944
PiperOrigin-RevId: 935400242
Change-Id: Iecd907174441fbcfd02c106b912a7ff375c9098c
Also:
- Patched Filament to support building with Clang, so the default MuJoCo build
mode doesn't need to change. This should probably be upstreamed.
- Added missing Windows deps to MuJoCo Platform CMake config.
- Updated Studio CMake config to fix unresolved symbols issues on Windows.
PiperOrigin-RevId: 934612701
Change-Id: I3a34a5d274e1452c9cfef0e2868f2788b4b0c7e8
Also:
- Packages MuJoCo Studio as MuJoCoStudio.app in the MuJoCo.dmg.
- Fixes a Filament compile issue.
- Patches libwebp to fix compile error related to universal builds and forces
it to build as static.
- Removes the separate, obsolete "build_studio" step.
PiperOrigin-RevId: 934564785
Change-Id: I50c83283b5e138062e37d53926a5a77fdf99dbfa
For example when loading parent_merge.xml:
```
WARNING: Attach conflict when attaching 'child' to 'parent_merge', policy is 'merge'
timestep: parent has 0.005, child has 0.002, taking the minimum
iterations: parent has 50, child has 100, taking the maximum
flag 'Damper': added from child
```
When loading parent_error.xml:
```
XML Error: Attach conflict when attaching 'child' to 'parent_error', policy is 'error'
timestep: parent has 0.005, child has 0.002
iterations: parent has 50, child has 100
Element 'attach', line 10
```
PiperOrigin-RevId: 933620810
Change-Id: Ib477863b5ef763474d27fb4be5a4148be1d5d500
Compiler warnings are now accumulated in a vector of strings within the mjSpec object. New API functions `mjs_numWarnings` and `mjs_getWarning` are added to access these warnings. The compiler's log handler now chains warnings to the global log handler, ensuring they are still displayed immediately. Call sites in `mj_loadXML`, `mj_compile`, and the Python and WASM bindings have been updated to use the new warning API.
PiperOrigin-RevId: 933361650
Change-Id: I47cab98a460c57b0898c0a1a43fce2a5b9648eb1
--
8ce7d8199ace95d0f429b0ca9169d290d167cee1 by Anas <anaselghoudane@gmail.com>:
Use box midpoint to choose finite-difference direction in jacobian_fd
When bounds are provided, `jacobian_fd` chooses each coordinate's
finite-difference direction so the perturbation steps away from the nearer
bound. It compared `x` against `0.5 * (bounds[1] - bounds[0])`, which is half
the box *width*, not the box midpoint. For bounds that are not centered on the
origin this selects the wrong direction, and at the lower bound the perturbation
steps outside the box.
Compare against the midpoint `0.5 * (bounds[0] + bounds[1])` instead. Adds a
regression test checking that all residual evaluations stay within an off-center
box when `x` is at the lower bound; it fails before this change and passes after.
--
cfa085484c30df808362898e322de8adc6660b59 by Kevin Zakka <kevinarmandzakka@gmail.com>:
Expand jacobian_fd bounds test and avoid midpoint overflow
Use the distributive form `0.5*lo + 0.5*hi` instead of
`0.5*(lo+hi)` to avoid overflow for extreme bound values.
Expand the single-case test into a parameterized subTest covering
all four boundary positions (lower/upper of positive and negative
off-center boxes), and rename it to `test_jacobian_fd_respects_bounds`.
COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3301 from Nas01010101:fix/minimize-fd-box-midpoint cfa085484c30df808362898e322de8adc6660b59
PiperOrigin-RevId: 933224876
Change-Id: I833cfe3324876cdeb7ca680c23d1d8a4d16adcf1
Correct argument types for timeconst and range parameters in pybind11
python bindings from C arrays to std::array.
Fixes#3282, #3282, #3318
Thanks to @Abzaek for original PRs
PiperOrigin-RevId: 932423401
Change-Id: Ic30ba076913693f5c0e545789690e8b0fa444390
Allows other files (e.g. mjrfilament) to define functions that
will be added to the introspection output.
PiperOrigin-RevId: 932403177
Change-Id: Ie2d2c6be67f0706463fdec4fc498364125e05dad
- Move SimToView and ViewToSim dataclasses from async.py to viewer_protocol.py (adding a user_data field) to consolidate IPC protocol definitions.
- Remove the simulated Network class and latency UI controls from async.py to simplify the example and focus on core multiprocessing communication.
- Use parser.parse() in main() for cleaner and more direct MuJoCo model loading.
- Add cancel_join_thread() to multiprocessing queues and a join timeout to prevent atexit handlers from blocking during process shutdown.
PiperOrigin-RevId: 932327625
Change-Id: If91777dba934814b3f9faa17f9055869920575d7
Widen mju_error_msg buffer from 1024 to 2048 and replace strncpy with
snprintf to avoid -Wformat-truncation and -Wstringop-truncation.
PiperOrigin-RevId: 930982013
Change-Id: I0fcd726e5ed1ad28594bd4ef55b8b1ae72020043
This change adds py::gil_scoped_release to various functions in the parser, renderer, sim and ux modules of the MuJoCo Studio Python bindings. This allows other Python threads to execute while these C++ functions, which can sometimes be time-consuming, are running. The two heaviest operations Present() (rendering) and Advance() (physics) now both release the GIL in C++.
PiperOrigin-RevId: 930645361
Change-Id: Ib239fb54edc7ac0d8b1d94bec8c57a447d5f4d27
Adds py::gil_scoped_release no_gil; to mujoco::studio::Viewer methods to release the Python GIL during C++ execution.
PiperOrigin-RevId: 930482271
Change-Id: I590794109418516ec5d9e8b536085560a1d36314