mujoco-mojo 2.3.7__tar.gz → 2.3.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (397) hide show
  1. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/PKG-INFO +50 -38
  2. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/README.md +49 -37
  3. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/index.md +10 -1
  4. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/stylesheets/extra.css +13 -0
  5. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/generate-script.md +2 -2
  6. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/monitor.md +4 -3
  7. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/mosaic.md +18 -18
  8. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/optimization.md +1 -1
  9. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/runtime-script.md +2 -2
  10. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/mkdocs.yml +5 -1
  11. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/pyproject.toml +1 -1
  12. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/asset_attr/mesh.py +5 -1
  13. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/inertial.py +32 -7
  14. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mojo_model.py +17 -0
  15. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/runtime/runtime_manager.py +6 -1
  16. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/runtime/signal_manager.py +31 -0
  17. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/runtime/video_recorder.py +91 -10
  18. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/dataframe.py +16 -3
  19. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/defaults.py +2 -0
  20. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/plot_config.py +16 -6
  21. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/routers/monitor.py +9 -0
  22. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/routers/mosaic.py +55 -0
  23. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/partials/trial_viewer/_chart.html +188 -110
  24. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/partials/trial_viewer/_media_player.html +6 -2
  25. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/partials/trial_viewer/_signal_lab.html +5 -4
  26. mujoco_mojo-2.3.9/src/mujoco_mojo/utils/layers/dojo/templates/partials/trial_viewer/_trial_logs.html +241 -0
  27. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/js/trial-viewer.js +290 -47
  28. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/src/lib/plot-config.generated.ts +33 -3
  29. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/src/models.ts +13 -0
  30. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/src/trial-viewer.ts +360 -50
  31. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/trial_viewer.html +1 -0
  32. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/reloaded.py +32 -4
  33. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/log.py +43 -1
  34. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/proximity_mixin.py +10 -0
  35. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/runner.py +16 -4
  36. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/statusing.py +29 -0
  37. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/inertial_test.py +31 -3
  38. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/runtime/monte_carlo_bumper.py +5 -0
  39. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/utils/dataframe_test.py +7 -8
  40. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/.gitattributes +0 -0
  41. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/.github/workflows/docs.yml +0 -0
  42. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/.github/workflows/release.yml +0 -0
  43. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/.gitignore +0 -0
  44. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/.pre-commit-config.yaml +0 -0
  45. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/.python-version +0 -0
  46. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/.vscode/settings.json +0 -0
  47. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/LICENSE +0 -0
  48. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/TODO.md +0 -0
  49. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/about.md +0 -0
  50. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/dark-hero-logo.png +0 -0
  51. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/dark-hero-logo.svg +0 -0
  52. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/dark-logo.svg +0 -0
  53. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/light-hero-logo.svg +0 -0
  54. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/light-logo.svg +0 -0
  55. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/logo.svg +0 -0
  56. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/mesh/bunny_original.jpg +0 -0
  57. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/mesh/bunny_with_coacd.jpg +0 -0
  58. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/mesh/bunny_without_coacd.jpg +0 -0
  59. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/mesh/frustums.jpg +0 -0
  60. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/mesh/proximity/convex_hull_wireframe.jpg +0 -0
  61. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/mesh/proximity/real_wireframe.jpg +0 -0
  62. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/mesh/with_coacd.jpg +0 -0
  63. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/mesh/without_coacd.jpg +0 -0
  64. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/dark-export-options.jpg +0 -0
  65. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/dark-monitor-view.jpg +0 -0
  66. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/dark-mosaic-view.jpg +0 -0
  67. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/dark-notes-editor.jpg +0 -0
  68. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/dark-plot-editor.jpg +0 -0
  69. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/dark-selector-bar.jpg +0 -0
  70. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/dark-shapes-editor.jpg +0 -0
  71. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/generate-result.jpg +0 -0
  72. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/light-export-options.jpg +0 -0
  73. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/light-monitor-view.jpg +0 -0
  74. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/light-mosaic-view.jpg +0 -0
  75. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/light-notes-editor.jpg +0 -0
  76. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/light-plot-editor.jpg +0 -0
  77. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/light-selector-bar.jpg +0 -0
  78. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/light-shapes-editor.jpg +0 -0
  79. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/assets/user-guides/runtime-anim.gif +0 -0
  80. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/javascripts/favicon-switcher.js +0 -0
  81. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/javascripts/mojo-highlighter.js +0 -0
  82. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/javascripts/tablesort.js +0 -0
  83. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/MOJO_RUNTIME_REPORT.md +0 -0
  84. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/dojo.md +0 -0
  85. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/getting-started.md +0 -0
  86. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/init.md +0 -0
  87. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/monte_carlo_example.py +0 -0
  88. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/optimization_example.py +0 -0
  89. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/pose-context.md +0 -0
  90. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/pose_context_example.py +0 -0
  91. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/reloaded.md +0 -0
  92. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/docs/user-guides/running-jobs.md +0 -0
  93. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/examples/boxes_and_springs_monte_carlo.py +0 -0
  94. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/examples/boxes_and_springs_optimization.py +0 -0
  95. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/examples/tennis_racket_theorem.py +0 -0
  96. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/requirements.txt +0 -0
  97. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/scripts/copy_docs_examples_to_examples.py +0 -0
  98. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/scripts/fix_smart_quotes.py +0 -0
  99. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/scripts/gen_ref_pages.py +0 -0
  100. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/scripts/gen_ts_models.py +0 -0
  101. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/scripts/templating/filestomake.txt +0 -0
  102. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/scripts/templating/make_sensors.py +0 -0
  103. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/scripts/templating/sensor_template.py +0 -0
  104. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/__about__.py +0 -0
  105. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/__init__.py +0 -0
  106. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/base.py +0 -0
  107. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/meta.py +0 -0
  108. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mj_state.py +0 -0
  109. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/__init__.py +0 -0
  110. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/defaults.py +0 -0
  111. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/dependency_path.py +0 -0
  112. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/extension.py +0 -0
  113. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/meta/__init__.py +0 -0
  114. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/meta/frame.py +0 -0
  115. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/meta/include.py +0 -0
  116. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/meta/replicate.py +0 -0
  117. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco.py +0 -0
  118. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/__init__.py +0 -0
  119. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator.py +0 -0
  120. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/__init__.py +0 -0
  121. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/adhesion.py +0 -0
  122. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/base.py +0 -0
  123. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/cylinder.py +0 -0
  124. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/damper.py +0 -0
  125. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/dcmotor.py +0 -0
  126. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/general.py +0 -0
  127. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/intvelocity.py +0 -0
  128. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/motor.py +0 -0
  129. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/muscle.py +0 -0
  130. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/plugin.py +0 -0
  131. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/position.py +0 -0
  132. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/actuator_attr/velocity.py +0 -0
  133. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/asset.py +0 -0
  134. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/asset_attr/__init__.py +0 -0
  135. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/asset_attr/hfield.py +0 -0
  136. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/asset_attr/material.py +0 -0
  137. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/asset_attr/material_attr/__init__.py +0 -0
  138. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/asset_attr/material_attr/layer.py +0 -0
  139. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/asset_attr/model.py +0 -0
  140. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/asset_attr/texture.py +0 -0
  141. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body.py +0 -0
  142. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/__init__.py +0 -0
  143. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/attach.py +0 -0
  144. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/camera.py +0 -0
  145. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/composite.py +0 -0
  146. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/composite_attr/__init__.py +0 -0
  147. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/composite_attr/geom.py +0 -0
  148. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/composite_attr/joint.py +0 -0
  149. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/composite_attr/site.py +0 -0
  150. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/composite_attr/skin.py +0 -0
  151. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/flexcomp.py +0 -0
  152. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/flexcomp_attr/__init__.py +0 -0
  153. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/flexcomp_attr/contact.py +0 -0
  154. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/flexcomp_attr/edge.py +0 -0
  155. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/flexcomp_attr/elasticity.py +0 -0
  156. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/flexcomp_attr/pin.py +0 -0
  157. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/free_joint.py +0 -0
  158. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/geom.py +0 -0
  159. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/joint.py +0 -0
  160. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/light.py +0 -0
  161. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/plugin.py +0 -0
  162. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/body_attr/site.py +0 -0
  163. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/compiler.py +0 -0
  164. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/compiler_attr/__init__.py +0 -0
  165. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/compiler_attr/lengthrange.py +0 -0
  166. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/contact.py +0 -0
  167. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/contact_attr/__init__.py +0 -0
  168. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/contact_attr/exclude.py +0 -0
  169. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/contact_attr/pair.py +0 -0
  170. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/deformable.py +0 -0
  171. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/deformable_attr/__init__.py +0 -0
  172. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/deformable_attr/flex.py +0 -0
  173. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/deformable_attr/flex_attr/__init__.py +0 -0
  174. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/deformable_attr/flex_attr/contact.py +0 -0
  175. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/deformable_attr/flex_attr/edge.py +0 -0
  176. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/deformable_attr/flex_attr/elasticity.py +0 -0
  177. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/deformable_attr/skin.py +0 -0
  178. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/deformable_attr/skin_attr/__init__.py +0 -0
  179. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/deformable_attr/skin_attr/bone.py +0 -0
  180. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/equality.py +0 -0
  181. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/equality_attr/__init__.py +0 -0
  182. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/equality_attr/connect.py +0 -0
  183. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/equality_attr/equality_base.py +0 -0
  184. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/equality_attr/flex.py +0 -0
  185. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/equality_attr/flexstrain.py +0 -0
  186. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/equality_attr/flexvert.py +0 -0
  187. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/equality_attr/joint.py +0 -0
  188. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/equality_attr/tendon.py +0 -0
  189. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/equality_attr/weld.py +0 -0
  190. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/keyframe.py +0 -0
  191. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/keyframe_attr/__init__.py +0 -0
  192. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/keyframe_attr/key.py +0 -0
  193. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/option.py +0 -0
  194. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/option_attr/__init__.py +0 -0
  195. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/option_attr/flag.py +0 -0
  196. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor.py +0 -0
  197. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/__init__.py +0 -0
  198. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/accelerometer.py +0 -0
  199. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/actuatorfrc.py +0 -0
  200. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/actuatorpos.py +0 -0
  201. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/actuatorvel.py +0 -0
  202. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/ballangvel.py +0 -0
  203. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/ballquat.py +0 -0
  204. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/base.py +0 -0
  205. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/base_collision.py +0 -0
  206. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/camprojection.py +0 -0
  207. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/clock.py +0 -0
  208. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/contact.py +0 -0
  209. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/distance.py +0 -0
  210. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/e_kinetic.py +0 -0
  211. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/e_potential.py +0 -0
  212. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/force.py +0 -0
  213. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/frameangacc.py +0 -0
  214. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/frameangvel.py +0 -0
  215. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/framelinacc.py +0 -0
  216. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/framelinvel.py +0 -0
  217. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/framepos.py +0 -0
  218. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/framequat.py +0 -0
  219. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/framexaxis.py +0 -0
  220. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/frameyaxis.py +0 -0
  221. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/framezaxis.py +0 -0
  222. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/fromto.py +0 -0
  223. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/gyro.py +0 -0
  224. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/insidesite.py +0 -0
  225. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/jointactuatorfrc.py +0 -0
  226. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/jointlimitfrc.py +0 -0
  227. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/jointlimitpos.py +0 -0
  228. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/jointlimitvel.py +0 -0
  229. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/jointpos.py +0 -0
  230. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/jointvel.py +0 -0
  231. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/magnetometer.py +0 -0
  232. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/normal.py +0 -0
  233. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/plugin.py +0 -0
  234. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/rangefinder.py +0 -0
  235. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/subtreeangmom.py +0 -0
  236. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/subtreecom.py +0 -0
  237. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/subtreelinvel.py +0 -0
  238. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/tactile.py +0 -0
  239. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/tendonactuatorfrc.py +0 -0
  240. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/tendonlimitfrc.py +0 -0
  241. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/tendonlimitpos.py +0 -0
  242. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/tendonlimitvel.py +0 -0
  243. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/tendonpos.py +0 -0
  244. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/tendonvel.py +0 -0
  245. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/torque.py +0 -0
  246. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/touch.py +0 -0
  247. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/user.py +0 -0
  248. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/sensor_attr/velocimeter.py +0 -0
  249. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/size.py +0 -0
  250. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/statistic.py +0 -0
  251. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/tendon.py +0 -0
  252. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/tendon_attr/__init__.py +0 -0
  253. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/tendon_attr/fixed.py +0 -0
  254. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/tendon_attr/fixed_attr/__init__.py +0 -0
  255. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/tendon_attr/fixed_attr/joint.py +0 -0
  256. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/tendon_attr/spatial.py +0 -0
  257. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/tendon_attr/spatial_attr/__init__.py +0 -0
  258. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/tendon_attr/spatial_attr/geom.py +0 -0
  259. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/tendon_attr/spatial_attr/pulley.py +0 -0
  260. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/tendon_attr/spatial_attr/site.py +0 -0
  261. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/tendon_attr/tendon_base.py +0 -0
  262. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/visual.py +0 -0
  263. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/visual_attr/__init__.py +0 -0
  264. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/visual_attr/global_.py +0 -0
  265. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/visual_attr/headlight.py +0 -0
  266. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/visual_attr/map.py +0 -0
  267. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/visual_attr/quality.py +0 -0
  268. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/visual_attr/rgba.py +0 -0
  269. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/mujoco_attr/visual_attr/scale.py +0 -0
  270. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/orientation.py +0 -0
  271. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/plugin.py +0 -0
  272. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/pose.py +0 -0
  273. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/pose_context.py +0 -0
  274. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/position.py +0 -0
  275. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/mjcf/xml_model.py +0 -0
  276. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/runtime/__init__.py +0 -0
  277. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/runtime/load.py +0 -0
  278. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/settings.py +0 -0
  279. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/stochas/__init__.py +0 -0
  280. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/templates/__init__.py +0 -0
  281. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/templates/dojo.sh +0 -0
  282. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/templates/monte_carlo.py +0 -0
  283. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/templates/optimization.py +0 -0
  284. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/templates/reloaded.sh +0 -0
  285. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/templates/run_mc.sh +0 -0
  286. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/templates/run_opt.sh +0 -0
  287. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/typing.py +0 -0
  288. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/__init__.py +0 -0
  289. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/color.py +0 -0
  290. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/filters/__init__.py +0 -0
  291. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/filters/filters.py +0 -0
  292. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/interp.py +0 -0
  293. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/__init__.py +0 -0
  294. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/cli.py +0 -0
  295. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/__init__.py +0 -0
  296. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/lab_executor.py +0 -0
  297. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/main.py +0 -0
  298. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/routers/__init__.py +0 -0
  299. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/routers/morph.py +0 -0
  300. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/routers/sensai.py +0 -0
  301. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/sensai/__init__.py +0 -0
  302. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/sensai/agent.py +0 -0
  303. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/shared.py +0 -0
  304. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/__init__.py +0 -0
  305. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/base.html +0 -0
  306. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/error.html +0 -0
  307. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/monitor.html +0 -0
  308. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/morph.html +0 -0
  309. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/mosaic.html +0 -0
  310. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/partials/_sensai.html +0 -0
  311. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/partials/trial_viewer/_header.html +0 -0
  312. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/partials/trial_viewer/_json_editor.html +0 -0
  313. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/partials/trial_viewer/_lab_trigger.html +0 -0
  314. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/partials/trial_viewer/_macros.html +0 -0
  315. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/partials/trial_viewer/_overlays.html +0 -0
  316. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/partials/trial_viewer/_series_panel.html +0 -0
  317. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/partials/trial_viewer/_trial_status.html +0 -0
  318. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/__init__.py +0 -0
  319. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/chime.mp3 +0 -0
  320. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/dark-logo.svg +0 -0
  321. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/js/__init__.py +0 -0
  322. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/js/main.js +0 -0
  323. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/js/monitor.js +0 -0
  324. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/js/mosaic.js +0 -0
  325. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/js/sensai.js +0 -0
  326. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/js/toast.d.ts +0 -0
  327. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/js/toast.d.ts.map +0 -0
  328. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/js/toast.js +0 -0
  329. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/light-logo.svg +0 -0
  330. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/main.css +0 -0
  331. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/build.mjs +0 -0
  332. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/package-lock.json +0 -0
  333. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/package.json +0 -0
  334. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/src/cm-bundle.ts +0 -0
  335. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/src/lib/format.ts +0 -0
  336. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/src/lib/options.ts +0 -0
  337. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/src/lib/toast.ts +0 -0
  338. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/src/monitor.ts +0 -0
  339. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/src/mosaic.ts +0 -0
  340. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/src/sensai.ts +0 -0
  341. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/src/store.ts +0 -0
  342. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/src/types/global.d.ts +0 -0
  343. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/ts/tsconfig.json +0 -0
  344. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/vendored/__init__.py +0 -0
  345. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/vendored/alpine.min.js +0 -0
  346. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/vendored/codemirror.bundle.js +0 -0
  347. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/vendored/confetti.browser.min.js +0 -0
  348. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/vendored/iro.min.js +0 -0
  349. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/vendored/litegraph.min.css +0 -0
  350. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/vendored/litegraph.min.js +0 -0
  351. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/vendored/lz-string.min.js +0 -0
  352. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/vendored/plotly-3.4.0.min.js +0 -0
  353. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/layers/dojo/templates/static/vendored/tailwind.min.js +0 -0
  354. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/proximity.py +0 -0
  355. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/utils/utils.py +0 -0
  356. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/src/mujoco_mojo/visualization.py +0 -0
  357. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/.gitignore +0 -0
  358. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/make_skybox.py +0 -0
  359. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/meshes/ball.stl +0 -0
  360. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/meshes/bunny2.stl +0 -0
  361. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/meshes/cup.stl +0 -0
  362. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/body_test.py +0 -0
  363. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/equality_test.py +0 -0
  364. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/joint_test.py +0 -0
  365. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/mesh.py +0 -0
  366. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/mujoco_test.py +0 -0
  367. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/orientation_test.py +0 -0
  368. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/pos_test.py +0 -0
  369. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/pose_graph_test.py +0 -0
  370. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/pose_test.py +0 -0
  371. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/site_test.py +0 -0
  372. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/visualization_test.py +0 -0
  373. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/mjcf/xml_model_test.py +0 -0
  374. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/model_with_skybox.xml +0 -0
  375. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/monte_carlo_test/asset_image.png +0 -0
  376. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/monte_carlo_test/monte_carlo.py +0 -0
  377. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/monte_carlo_test/overrides.json +0 -0
  378. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/monte_carlo_test/running_with_slurm.sh +0 -0
  379. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/one_off/proximity/dojo.sh +0 -0
  380. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/one_off/proximity/reloaded.sh +0 -0
  381. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/one_off/proximity/run.sh +0 -0
  382. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/one_off/proximity/simulation.py +0 -0
  383. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/runtime/conftest.py +0 -0
  384. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/runtime/loads_test.py +0 -0
  385. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/runtime/mojo_model_test.py +0 -0
  386. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/runtime/optimizer_bumper.py +0 -0
  387. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/runtime/runtime_manager_test.py +0 -0
  388. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/runtime/settings_test.py +0 -0
  389. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/runtime/signal_manager_test.py +0 -0
  390. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/smoke_test.py +0 -0
  391. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/test_writer.py +0 -0
  392. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/utils/color_test.py +0 -0
  393. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/utils/filter_test.py +0 -0
  394. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/utils/interp_test.py +0 -0
  395. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/utils/proximity_test.py +0 -0
  396. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/tests/utils/utils_test.py +0 -0
  397. {mujoco_mojo-2.3.7 → mujoco_mojo-2.3.9}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mujoco-mojo
3
- Version: 2.3.7
3
+ Version: 2.3.9
4
4
  Summary: A complete MJCF lifecycle and trial orchestration suite for MuJoCo, powered by Pydantic v2.
5
5
  Project-URL: Homepage, https://github.com/Hydrowelder/mujoco-mojo
6
6
  Project-URL: Documentation, https://hydrowelder.github.io/mujoco-mojo/
@@ -103,13 +103,14 @@ A **complete MJCF lifecycle and trial orchestration suite** for MuJoCo, powered
103
103
 
104
104
  **MuJoCo Mojo** bridges the gap between static XML modeling and large-scale simulation research. It provides a strongly-typed bridge for building models and a robust execution engine for running them at scale.
105
105
 
106
- * **Model:** Build MJCFs via **validated Python objects** allowing for programatic generation.
107
- * **Scale:** Execute **multi-threaded Monte Carlo trials** with built-in resume logic.
108
- * **Monitor:** Track progress via a **zero-dependency web dashboard** and persistent logs.
109
- * **Assess:** Quickly view **interactive results** of a trial in context of others.
110
- * **Reproduce:** Automatic **environment snapshotting** (`requirements.txt`) for every job.
106
+ - **Model:** Build MJCFs via **validated Python objects** allowing for programatic generation.
107
+ - **Scale:** Execute **multi-threaded Monte Carlo trials** with built-in resume logic.
108
+ - **Monitor:** Track progress via a **zero-dependency web dashboard** and persistent logs.
109
+ - **Assess:** Quickly view **interactive results** of a trial in context of others.
110
+ - **Reproduce:** Automatic **environment snapshotting** (`requirements.txt`) for every job.
111
111
 
112
112
  ## Installation
113
+
113
114
  Install using `uv` (recommended):
114
115
 
115
116
  ```bash
@@ -124,34 +125,41 @@ pip install mujoco-mojo
124
125
 
125
126
  ---
126
127
 
127
-
128
128
  ## Features
129
129
 
130
130
  ### MJCF Tools
131
131
 
132
- * **Strongly-Typed Elements:** MJCF components backed by Pydantic v2 for immediate validation.
133
- * **Semantic Validation:** Early detection of structural errors and attribute mismatches before the engine starts.
134
- * **MuJoCo Alignment:** Designed to mirror MuJoCo’s XML schema closely (no magic abstractions)
135
- * **Object Enumerations:** Embedded MuJoCo object mappings to simplify retrieving `mjOBJ` IDs.
136
- * **Asset Sharing:** Specialized handling of dependency by remapping assets to become shared allows for space efficient execution of complex models
132
+ - **Strongly-Typed Elements:** MJCF components backed by Pydantic v2 for immediate validation.
133
+ - **Semantic Validation:** Early detection of structural errors and attribute mismatches before the engine starts.
134
+ - **MuJoCo Alignment:** Designed to mirror MuJoCo’s XML schema closely (no magic abstractions)
135
+ - **Object Enumerations:** Embedded MuJoCo object mappings to simplify retrieving `mjOBJ` IDs.
136
+ - **Asset Sharing:** Specialized handling of dependency by remapping assets to become shared allows for space efficient execution of complex models
137
+
138
+ ### Runtime Toolkit
139
+
140
+ - **Forcing Functions:** A library of typed `Load` definitions (spring-dampers, point-to-point forces, friction, and more) that apply themselves including reaction forces.
141
+ - **Proximity Sensing:** Built-in distance and closest-point tracking between sites and bodies, exposed as both telemetry signals and live overlays with no extra instrumentation. Works on concave geometry meshes.
142
+ - **Structured Telemetry:** A single `post`/`track` call records any value into a hierarchical namespace during simulations. This include prebuilt `request` calls for commonly desired values.
143
+ - **Video Recording:** Multi-camera MP4/WebM/GIF capture synced to simulation time, with playback-speed control, force/proximity overlays, on-frame labels, and single-frame snapshots.
137
144
 
138
145
  ### Job Utilities
139
146
 
140
147
  #### Campaign Orchestration
141
148
 
142
- * **Multi-Threaded Execution:** Single or multi-threaded trial execution
143
- * **Environment Snapshotting:** Automatically record installed Python packages to `requirements.txt` for job recreation (works with `uv` or `pip`)
144
- * **Resume Logic:** Resume a previously started job without rerunning previous cases
145
- * **Robust Logging:** Built in Rich logging for terminal and a rotating file handler for persistent logs and status files for insight on trial progress
146
- * **Global Overrides:** Force specific values onto distributions via CLI or JSON overrides to test "golden" cases.
149
+ - **Multi-Threaded Execution:** Single or multi-threaded trial execution
150
+ - **Environment Snapshotting:** Automatically record installed Python packages to `requirements.txt` for job recreation (works with `uv` or `pip`)
151
+ - **Resume Logic:** Resume a previously started job without rerunning previous cases
152
+ - **Robust Logging:** Built in Rich logging for terminal and a rotating file handler for persistent logs and status files for insight on trial progress
153
+ - **Global Overrides:** Force specific values onto distributions via CLI or JSON overrides to test "golden" cases.
147
154
 
148
155
  #### Monte Carlo
149
156
 
150
- * **Reproducible Sampling:** Random draw tools for Monte Carlo or rerun with global variable override
151
- * End of run summary with metric to help perform a state of health check
152
- * Support for running jobs with SLURM for distributed compute
157
+ - **Reproducible Sampling:** Random draw tools for Monte Carlo or rerun with global variable override
158
+ - End of run summary with metric to help perform a state of health check
159
+ - Support for running jobs with SLURM for distributed compute
153
160
 
154
161
  > [!TIP]
162
+ >
155
163
  > ```bash
156
164
  > mujoco-mojo run monte-carlo \
157
165
  > --generator monte_carlo_test.Experiment.generate \
@@ -166,12 +174,13 @@ pip install mujoco-mojo
166
174
 
167
175
  #### Optimization
168
176
 
169
- * **Bayesian Search:** Intelligent design space navigation powered by Optuna integration.
170
- * **Design Variables:** Continuous (`DesignFloat`) and discrete (`DesignCategorical`) parameters evolved by the solver.
171
- * **Adaptive Refinement:** "Zoom" into promising neighborhoods by aggressively shrinking search bounds on resume.
172
- * **Stochastic Robustness:** Multi-evaluation trials that average scores over different seeds to filter out noisy physics outliers.
177
+ - **Bayesian Search:** Intelligent design space navigation powered by Optuna integration.
178
+ - **Design Variables:** Continuous (`DesignFloat`) and discrete (`DesignCategorical`) parameters evolved by the solver.
179
+ - **Adaptive Refinement:** "Zoom" into promising neighborhoods by aggressively shrinking search bounds on resume.
180
+ - **Stochastic Robustness:** Multi-evaluation trials that average scores over different seeds to filter out noisy physics outliers.
173
181
 
174
182
  > [!TIP]
183
+ >
175
184
  > ```bash
176
185
  > mujoco-mojo run optimiztion \
177
186
  > -g sim.generate \
@@ -190,30 +199,33 @@ A zero-dependency, offline-first web suite for monitoring and analyzing your sim
190
199
 
191
200
  #### Monitor: Real-Time Oversight
192
201
 
193
- * **Live Progress Tracking:** Dynamic progress bars and color-coded status cards provide a high-level view of your Monte Carlo runs.
194
- * **Success/Failure Analytics:** Automatic categorization of trials with built-in data integrity checks to identify "empty" vs. "failed" runs.
195
- * **Sensory Feedback:** Optional audio cues and visual celebrations let you know exactly when a multi-hour job hits 100%.
196
- * **Deep-Linked Navigation:** Jump straight from the monitor to any individual trial in the viewer with one click.
202
+ - **Live Progress Tracking:** Dynamic progress bars and color-coded status cards provide a high-level view of your Monte Carlo runs.
203
+ - **Success/Failure Analytics:** Automatic categorization of trials with built-in data integrity checks to identify "empty" vs. "failed" runs.
204
+ - **Sensory Feedback:** Optional audio cues and visual celebrations let you know exactly when a multi-hour job hits 100%.
205
+ - **Deep-Linked Navigation:** Jump straight from the monitor to any individual trial in the viewer with one click.
197
206
 
198
207
  #### Mosaic: Advanced Telemetry Analysis
199
208
 
200
- * **High-Fidelity Plotting:** Hardware-accelerated visualization using Plotly.js for seamless zooming and panning through millions of data points.
201
- * **Dynamic Versus Mode:** Overlay current telemetry against previous trials using an intuitive range-selection slider for instant regression testing.
202
- * **Regex-Powered Filtering:** Navigate high-dimensional datasets using a "folder-style" signal selector with suffix and regex support.
203
- * **State Persistence & Sharing:** Every view is captured in a shareable, compressed URL by pasting a link to share your exact configuration.
204
- * **Pro-Grade Tooling:** Built-in JSON configuration editor, drag-and-drop config restoration, and multi-format exports (SVG, PNG, CSV).
205
- * **Keyboard-First Design:** Full hotkey support for warping between trials and managing views without leaving the home row.
209
+ - **High-Fidelity Plotting:** Hardware-accelerated visualization using Plotly.js for seamless zooming and panning through millions of data points.
210
+ - **Dynamic Versus Mode:** Overlay current telemetry against previous trials using an intuitive range-selection slider for instant regression testing.
211
+ - **Regex-Powered Filtering:** Navigate high-dimensional datasets using a "folder-style" signal selector with suffix and regex support.
212
+ - **State Persistence & Sharing:** Every view is captured in a shareable, compressed URL by pasting a link to share your exact configuration.
213
+ - **Pro-Grade Tooling:** Built-in JSON configuration editor, drag-and-drop config restoration, and multi-format exports (SVG, PNG, CSV).
214
+ - **Keyboard-First Design:** Full hotkey support for warping between trials and managing views without leaving the home row.
206
215
 
207
216
  ### Reloaded
208
217
 
209
218
  A rapid prototyping loop that allows you to modify physics logic and model architecture on the fly without ever closing the visualizer.
210
219
 
211
- * **Module Hot-Reloading:** Recursively reloads local Python modules and MJCF logic, allowing code changes to propagate instantly to the active simulation.
212
- * **Unified Visualizer Bridge:** Synchronized visualization of custom force and torque vectors across native OpenGL, Viser web interfaces, and video recordings.
213
- * **Interactive Prototyping:** A developer-centric command loop to toggle playback speeds, repeat last commands, or trigger "generation-only" mode for rapid MJCF debugging.
214
- * **Asset Persistence:** Automatically dumps current MJCF snapshots and model configurations to a workspace directory for post-hoc analysis or version tracking.
220
+ - **Module Hot-Reloading:** Recursively reloads local Python modules and MJCF logic, allowing code changes to propagate instantly to the active simulation.
221
+ - **Unified Visualizer Bridge:** Synchronized visualization of custom force and torque vectors across native OpenGL, Viser web interfaces, and video recordings.
222
+ - **Multiple Viewer Backends:** Drive the same reload/sync pipeline through either the native MuJoCo OpenGL viewer or a Viser web viewer.
223
+ - **Interactive Prototyping:** A developer-centric command loop to toggle playback speeds, repeat last commands, watch for file changes and auto-reload, switch telemetry recording on or off mid-session, or trigger "generation-only" mode for rapid MJCF debugging.
224
+ - **Live Session Controls:** Adjust the seed and trial number on the fly with `seed <N>` and `trial <N>`, without restarting the loop.
225
+ - **Asset Persistence:** Automatically dumps current MJCF snapshots and model configurations to a workspace directory for post-hoc analysis or version tracking.
215
226
 
216
227
  > [!TIP]
228
+ >
217
229
  > ```bash
218
230
  > mujoco-mojo reloaded \
219
231
  > --generator monte_carlo_test.Experiment.generate \
@@ -38,13 +38,14 @@ A **complete MJCF lifecycle and trial orchestration suite** for MuJoCo, powered
38
38
 
39
39
  **MuJoCo Mojo** bridges the gap between static XML modeling and large-scale simulation research. It provides a strongly-typed bridge for building models and a robust execution engine for running them at scale.
40
40
 
41
- * **Model:** Build MJCFs via **validated Python objects** allowing for programatic generation.
42
- * **Scale:** Execute **multi-threaded Monte Carlo trials** with built-in resume logic.
43
- * **Monitor:** Track progress via a **zero-dependency web dashboard** and persistent logs.
44
- * **Assess:** Quickly view **interactive results** of a trial in context of others.
45
- * **Reproduce:** Automatic **environment snapshotting** (`requirements.txt`) for every job.
41
+ - **Model:** Build MJCFs via **validated Python objects** allowing for programatic generation.
42
+ - **Scale:** Execute **multi-threaded Monte Carlo trials** with built-in resume logic.
43
+ - **Monitor:** Track progress via a **zero-dependency web dashboard** and persistent logs.
44
+ - **Assess:** Quickly view **interactive results** of a trial in context of others.
45
+ - **Reproduce:** Automatic **environment snapshotting** (`requirements.txt`) for every job.
46
46
 
47
47
  ## Installation
48
+
48
49
  Install using `uv` (recommended):
49
50
 
50
51
  ```bash
@@ -59,34 +60,41 @@ pip install mujoco-mojo
59
60
 
60
61
  ---
61
62
 
62
-
63
63
  ## Features
64
64
 
65
65
  ### MJCF Tools
66
66
 
67
- * **Strongly-Typed Elements:** MJCF components backed by Pydantic v2 for immediate validation.
68
- * **Semantic Validation:** Early detection of structural errors and attribute mismatches before the engine starts.
69
- * **MuJoCo Alignment:** Designed to mirror MuJoCo’s XML schema closely (no magic abstractions)
70
- * **Object Enumerations:** Embedded MuJoCo object mappings to simplify retrieving `mjOBJ` IDs.
71
- * **Asset Sharing:** Specialized handling of dependency by remapping assets to become shared allows for space efficient execution of complex models
67
+ - **Strongly-Typed Elements:** MJCF components backed by Pydantic v2 for immediate validation.
68
+ - **Semantic Validation:** Early detection of structural errors and attribute mismatches before the engine starts.
69
+ - **MuJoCo Alignment:** Designed to mirror MuJoCo’s XML schema closely (no magic abstractions)
70
+ - **Object Enumerations:** Embedded MuJoCo object mappings to simplify retrieving `mjOBJ` IDs.
71
+ - **Asset Sharing:** Specialized handling of dependency by remapping assets to become shared allows for space efficient execution of complex models
72
+
73
+ ### Runtime Toolkit
74
+
75
+ - **Forcing Functions:** A library of typed `Load` definitions (spring-dampers, point-to-point forces, friction, and more) that apply themselves including reaction forces.
76
+ - **Proximity Sensing:** Built-in distance and closest-point tracking between sites and bodies, exposed as both telemetry signals and live overlays with no extra instrumentation. Works on concave geometry meshes.
77
+ - **Structured Telemetry:** A single `post`/`track` call records any value into a hierarchical namespace during simulations. This include prebuilt `request` calls for commonly desired values.
78
+ - **Video Recording:** Multi-camera MP4/WebM/GIF capture synced to simulation time, with playback-speed control, force/proximity overlays, on-frame labels, and single-frame snapshots.
72
79
 
73
80
  ### Job Utilities
74
81
 
75
82
  #### Campaign Orchestration
76
83
 
77
- * **Multi-Threaded Execution:** Single or multi-threaded trial execution
78
- * **Environment Snapshotting:** Automatically record installed Python packages to `requirements.txt` for job recreation (works with `uv` or `pip`)
79
- * **Resume Logic:** Resume a previously started job without rerunning previous cases
80
- * **Robust Logging:** Built in Rich logging for terminal and a rotating file handler for persistent logs and status files for insight on trial progress
81
- * **Global Overrides:** Force specific values onto distributions via CLI or JSON overrides to test "golden" cases.
84
+ - **Multi-Threaded Execution:** Single or multi-threaded trial execution
85
+ - **Environment Snapshotting:** Automatically record installed Python packages to `requirements.txt` for job recreation (works with `uv` or `pip`)
86
+ - **Resume Logic:** Resume a previously started job without rerunning previous cases
87
+ - **Robust Logging:** Built in Rich logging for terminal and a rotating file handler for persistent logs and status files for insight on trial progress
88
+ - **Global Overrides:** Force specific values onto distributions via CLI or JSON overrides to test "golden" cases.
82
89
 
83
90
  #### Monte Carlo
84
91
 
85
- * **Reproducible Sampling:** Random draw tools for Monte Carlo or rerun with global variable override
86
- * End of run summary with metric to help perform a state of health check
87
- * Support for running jobs with SLURM for distributed compute
92
+ - **Reproducible Sampling:** Random draw tools for Monte Carlo or rerun with global variable override
93
+ - End of run summary with metric to help perform a state of health check
94
+ - Support for running jobs with SLURM for distributed compute
88
95
 
89
96
  > [!TIP]
97
+ >
90
98
  > ```bash
91
99
  > mujoco-mojo run monte-carlo \
92
100
  > --generator monte_carlo_test.Experiment.generate \
@@ -101,12 +109,13 @@ pip install mujoco-mojo
101
109
 
102
110
  #### Optimization
103
111
 
104
- * **Bayesian Search:** Intelligent design space navigation powered by Optuna integration.
105
- * **Design Variables:** Continuous (`DesignFloat`) and discrete (`DesignCategorical`) parameters evolved by the solver.
106
- * **Adaptive Refinement:** "Zoom" into promising neighborhoods by aggressively shrinking search bounds on resume.
107
- * **Stochastic Robustness:** Multi-evaluation trials that average scores over different seeds to filter out noisy physics outliers.
112
+ - **Bayesian Search:** Intelligent design space navigation powered by Optuna integration.
113
+ - **Design Variables:** Continuous (`DesignFloat`) and discrete (`DesignCategorical`) parameters evolved by the solver.
114
+ - **Adaptive Refinement:** "Zoom" into promising neighborhoods by aggressively shrinking search bounds on resume.
115
+ - **Stochastic Robustness:** Multi-evaluation trials that average scores over different seeds to filter out noisy physics outliers.
108
116
 
109
117
  > [!TIP]
118
+ >
110
119
  > ```bash
111
120
  > mujoco-mojo run optimiztion \
112
121
  > -g sim.generate \
@@ -125,30 +134,33 @@ A zero-dependency, offline-first web suite for monitoring and analyzing your sim
125
134
 
126
135
  #### Monitor: Real-Time Oversight
127
136
 
128
- * **Live Progress Tracking:** Dynamic progress bars and color-coded status cards provide a high-level view of your Monte Carlo runs.
129
- * **Success/Failure Analytics:** Automatic categorization of trials with built-in data integrity checks to identify "empty" vs. "failed" runs.
130
- * **Sensory Feedback:** Optional audio cues and visual celebrations let you know exactly when a multi-hour job hits 100%.
131
- * **Deep-Linked Navigation:** Jump straight from the monitor to any individual trial in the viewer with one click.
137
+ - **Live Progress Tracking:** Dynamic progress bars and color-coded status cards provide a high-level view of your Monte Carlo runs.
138
+ - **Success/Failure Analytics:** Automatic categorization of trials with built-in data integrity checks to identify "empty" vs. "failed" runs.
139
+ - **Sensory Feedback:** Optional audio cues and visual celebrations let you know exactly when a multi-hour job hits 100%.
140
+ - **Deep-Linked Navigation:** Jump straight from the monitor to any individual trial in the viewer with one click.
132
141
 
133
142
  #### Mosaic: Advanced Telemetry Analysis
134
143
 
135
- * **High-Fidelity Plotting:** Hardware-accelerated visualization using Plotly.js for seamless zooming and panning through millions of data points.
136
- * **Dynamic Versus Mode:** Overlay current telemetry against previous trials using an intuitive range-selection slider for instant regression testing.
137
- * **Regex-Powered Filtering:** Navigate high-dimensional datasets using a "folder-style" signal selector with suffix and regex support.
138
- * **State Persistence & Sharing:** Every view is captured in a shareable, compressed URL by pasting a link to share your exact configuration.
139
- * **Pro-Grade Tooling:** Built-in JSON configuration editor, drag-and-drop config restoration, and multi-format exports (SVG, PNG, CSV).
140
- * **Keyboard-First Design:** Full hotkey support for warping between trials and managing views without leaving the home row.
144
+ - **High-Fidelity Plotting:** Hardware-accelerated visualization using Plotly.js for seamless zooming and panning through millions of data points.
145
+ - **Dynamic Versus Mode:** Overlay current telemetry against previous trials using an intuitive range-selection slider for instant regression testing.
146
+ - **Regex-Powered Filtering:** Navigate high-dimensional datasets using a "folder-style" signal selector with suffix and regex support.
147
+ - **State Persistence & Sharing:** Every view is captured in a shareable, compressed URL by pasting a link to share your exact configuration.
148
+ - **Pro-Grade Tooling:** Built-in JSON configuration editor, drag-and-drop config restoration, and multi-format exports (SVG, PNG, CSV).
149
+ - **Keyboard-First Design:** Full hotkey support for warping between trials and managing views without leaving the home row.
141
150
 
142
151
  ### Reloaded
143
152
 
144
153
  A rapid prototyping loop that allows you to modify physics logic and model architecture on the fly without ever closing the visualizer.
145
154
 
146
- * **Module Hot-Reloading:** Recursively reloads local Python modules and MJCF logic, allowing code changes to propagate instantly to the active simulation.
147
- * **Unified Visualizer Bridge:** Synchronized visualization of custom force and torque vectors across native OpenGL, Viser web interfaces, and video recordings.
148
- * **Interactive Prototyping:** A developer-centric command loop to toggle playback speeds, repeat last commands, or trigger "generation-only" mode for rapid MJCF debugging.
149
- * **Asset Persistence:** Automatically dumps current MJCF snapshots and model configurations to a workspace directory for post-hoc analysis or version tracking.
155
+ - **Module Hot-Reloading:** Recursively reloads local Python modules and MJCF logic, allowing code changes to propagate instantly to the active simulation.
156
+ - **Unified Visualizer Bridge:** Synchronized visualization of custom force and torque vectors across native OpenGL, Viser web interfaces, and video recordings.
157
+ - **Multiple Viewer Backends:** Drive the same reload/sync pipeline through either the native MuJoCo OpenGL viewer or a Viser web viewer.
158
+ - **Interactive Prototyping:** A developer-centric command loop to toggle playback speeds, repeat last commands, watch for file changes and auto-reload, switch telemetry recording on or off mid-session, or trigger "generation-only" mode for rapid MJCF debugging.
159
+ - **Live Session Controls:** Adjust the seed and trial number on the fly with `seed <N>` and `trial <N>`, without restarting the loop.
160
+ - **Asset Persistence:** Automatically dumps current MJCF snapshots and model configurations to a workspace directory for post-hoc analysis or version tracking.
150
161
 
151
162
  > [!TIP]
163
+ >
152
164
  > ```bash
153
165
  > mujoco-mojo reloaded \
154
166
  > --generator monte_carlo_test.Experiment.generate \
@@ -87,6 +87,13 @@ Install `mujoco-mojo` in your project using the following:
87
87
  - **Object Enumerations:** Embedded MuJoCo object mappings to simplify retrieving `mjOBJ` IDs.
88
88
  - **Asset Sharing:** Specialized handling of dependency by remapping assets to become shared allows for space efficient execution of complex models
89
89
 
90
+ ### Runtime Toolkit
91
+
92
+ - **Forcing Functions:** A library of typed `Load` definitions (spring-dampers, point-to-point forces, friction, and more) that apply themselves including reaction forces.
93
+ - **Proximity Sensing:** Built-in distance and closest-point tracking between sites and bodies, exposed as both telemetry signals and live overlays with no extra instrumentation. Works on concave geometry meshes.
94
+ - **Structured Telemetry:** A single `post`/`track` call records any value into a hierarchical namespace during simulations. This include prebuilt `request` calls for commonly desired values.
95
+ - **Video Recording:** Multi-camera MP4/WebM/GIF capture synced to simulation time, with playback-speed control, force/proximity overlays, on-frame labels, and single-frame snapshots.
96
+
90
97
  ### Job Utilities
91
98
 
92
99
  #### Campaign Orchestration
@@ -164,7 +171,9 @@ A rapid prototyping loop that allows you to modify physics logic and model archi
164
171
 
165
172
  - **Module Hot-Reloading:** Recursively reloads local Python modules and MJCF logic, allowing code changes to propagate instantly to the active simulation.
166
173
  - **Unified Visualizer Bridge:** Synchronized visualization of custom force and torque vectors across native OpenGL, Viser web interfaces, and video recordings.
167
- - **Interactive Prototyping:** A developer-centric command loop to toggle playback speeds, repeat last commands, or trigger "generation-only" mode for rapid MJCF debugging.
174
+ - **Multiple Viewer Backends:** Drive the same reload/sync pipeline through either the native MuJoCo OpenGL viewer or a Viser web viewer.
175
+ - **Interactive Prototyping:** A developer-centric command loop to toggle playback speeds, repeat last commands, watch for file changes and auto-reload, switch telemetry recording on or off mid-session, or trigger "generation-only" mode for rapid MJCF debugging.
176
+ - **Live Session Controls:** Adjust the seed and trial number on the fly with `seed <N>` and `trial <N>`, without restarting the loop.
168
177
  - **Asset Persistence:** Automatically dumps current MJCF snapshots and model configurations to a workspace directory for post-hoc analysis or version tracking.
169
178
 
170
179
  ??? example
@@ -77,6 +77,19 @@ h1,
77
77
  text-transform: uppercase;
78
78
  }
79
79
 
80
+ /* Figure captions are often wrapped in a glightbox <a> link and would otherwise
81
+ inherit the cyan link color and underline, which is hard to read at caption size.
82
+ text-decoration is drawn by the anchor itself, so it must be cleared there too. */
83
+ .md-typeset figure > a {
84
+ text-decoration: none;
85
+ }
86
+
87
+ .md-typeset figure figcaption {
88
+ color: var(--md-default-fg-color);
89
+ font-style: normal;
90
+ text-decoration: none;
91
+ }
92
+
80
93
  code,
81
94
  kbd,
82
95
  pre {
@@ -3,8 +3,8 @@
3
3
  !!! abstract
4
4
  The **Generate Script** is the heartbeat of your simulation pipeline. Its job is to programmatically assemble the MuJoCo MJCF model and perform all stochastic (random) draws. By the time this function returns, the simulation should be "frozen" in its initial state, ready for the physics engine to take over.
5
5
 
6
- <figure align="center" class="fade-in">
7
- <img src="../../assets/user-guides/generate-result.jpg" alt="Generate final result" style="width: 50%; height: auto;">
6
+ <figure markdown="span">
7
+ ![Mosaic dashboard view](../../assets/user-guides/generate-result.jpg){ width="50%" height="auto" }
8
8
  <figcaption>The visual result of the completed generator script: two translucent boxes with freejoints, spring attachment sites (red and blue spheres), and a central tracking site (fuchsia sphere), all set against a starry skybox.</figcaption>
9
9
  </figure>
10
10
 
@@ -5,12 +5,13 @@
5
5
 
6
6
  ---
7
7
 
8
- <figure align="center">
9
- <img src="../../assets/user-guides/light-monitor-view.jpg#only-light" alt="Mosaic dashboard view" style="width: 85%; height: auto;">
10
- <img src="../../assets/user-guides/dark-monitor-view.jpg#only-dark" alt="Mosaic dashboard view" style="width: 85%; height: auto;">
8
+ <figure markdown="span">
9
+ ![Mosaic dashboard view](../../assets/user-guides/light-monitor-view.jpg#only-light){ width="85%" height="auto" }
10
+ ![Mosaic dashboard view](../../assets/user-guides/dark-monitor-view.jpg#only-dark){ width="85%" height="auto" }
11
11
  <figcaption>A preview of the <b>Monitor</b> page showing a completed progress bar, job statistics, and links to <b>Mosaic</b> to assess individual trials.</figcaption>
12
12
  </figure>
13
13
 
14
+
14
15
  ## Real-Time Oversight
15
16
 
16
17
  The Monitor acts as a nexus for overseeing your `mujoco-mojo run` jobs. It works by monitoring the trial status files in your workspace and reflecting the global state of the simulation.
@@ -5,9 +5,9 @@
5
5
 
6
6
  ---
7
7
 
8
- <figure align="center">
9
- <img src="../../assets/user-guides/light-mosaic-view.jpg#only-light" alt="Mosaic dashboard view" style="width: 85%; height: auto;">
10
- <img src="../../assets/user-guides/dark-mosaic-view.jpg#only-dark" alt="Mosaic dashboard view" style="width: 85%; height: auto;">
8
+ <figure markdown="span">
9
+ ![Mosaic dashboard view](../../assets/user-guides/light-mosaic-view.jpg#only-light){ width="85%" height="auto" }
10
+ ![Mosaic dashboard view](../../assets/user-guides/dark-mosaic-view.jpg#only-dark){ width="85%" height="auto" }
11
11
  <figcaption>A preview of the <b>Mosaic</b> page showing run results for <code>trial_00</code>. Annotations indicate key moments in the simulations. Two telemetry signals per trial are shown with 9 additional trials displayed for comparison.</figcaption>
12
12
  </figure>
13
13
 
@@ -30,9 +30,9 @@ Trial Navigation
30
30
  !!! tip "Pro Tip: Regex Filtering"
31
31
  The dropdowns aren't just lists; they are Regex-aware. You can use the segment buttons (like quat, ctrl, or sens) to quickly filter down hundreds of signals to just the ones you need.
32
32
 
33
- <figure align="center">
34
- <img src="../../assets/user-guides/light-selector-bar.jpg#only-light" alt="Selector" style="width: 85%; height: auto;">
35
- <img src="../../assets/user-guides/dark-selector-bar.jpg#only-dark" alt="Selector bar" style="width: 85%; height: auto;">
33
+ <figure markdown="span">
34
+ ![Selector bar](../../assets/user-guides/light-selector-bar.jpg#only-light){ width="85%" height="auto" }
35
+ ![Selector bar](../../assets/user-guides/dark-selector-bar.jpg#only-dark){ width="85%" height="auto" }
36
36
  <figcaption>The dropdown for <b>Y-Axes</b> is active with the Bodies and box1 quick filters active. Two telemetry signals are selected showing the rotational and total kinetic energy.</figcaption>
37
37
  </figure>
38
38
 
@@ -50,9 +50,9 @@ This button compacts your current plot view (trial, selected data, plot appearan
50
50
 
51
51
  Adjust the visual style. Switch between Lines, Markers, or both. Change interpolation (Spline vs. Linear) or toggle Logarithmic scales for high-dynamic-range data.
52
52
 
53
- <figure align="center">
54
- <img src="../../assets/user-guides/light-plot-editor.jpg#only-light" alt="Plot editor menu" style="width: 40%; height: auto;">
55
- <img src="../../assets/user-guides/dark-plot-editor.jpg#only-dark" alt="Plot editor menu" style="width: 40%; height: auto;">
53
+ <figure markdown="span">
54
+ ![Plot editor menu](../../assets/user-guides/light-plot-editor.jpg#only-light){ width="40%" height="auto" }
55
+ ![Plot editor menu](../../assets/user-guides/dark-plot-editor.jpg#only-dark){ width="40%" height="auto" }
56
56
  <figcaption>The menu for <b>plot editor</b> is active. It shows the many dropdown options available to configure the layout of the plot area as well as the interaction behavior when hover over data.</figcaption>
57
57
  </figure>
58
58
 
@@ -63,9 +63,9 @@ Adjust the visual style. Switch between Lines, Markers, or both. Change interpol
63
63
  ???+ tip "Tip: Clickable Buttons"
64
64
  You can click on a note in the editor to "focus" on the note!
65
65
 
66
- <figure align="center">
67
- <img src="../../assets/user-guides/light-notes-editor.jpg#only-light" alt="Notes editor menu" style="width: 60%; height: auto;">
68
- <img src="../../assets/user-guides/dark-notes-editor.jpg#only-dark" alt="Notes editor menu" style="width: 60%; height: auto;">
66
+ <figure markdown="span">
67
+ ![Notes editor menu](../../assets/user-guides/light-notes-editor.jpg#only-light){ width="60%" height="auto" }
68
+ ![Notes editor menu](../../assets/user-guides/dark-notes-editor.jpg#only-dark){ width="60%" height="auto" }
69
69
  <figcaption>The menu for <b>notes editor</b> is active and in editing mode. A note is being edited. The plot area shows the two notes shown in the menu.</figcaption>
70
70
  </figure>
71
71
 
@@ -79,9 +79,9 @@ Add various shapes to the plot. After selecting an option in the menu, your mous
79
79
 
80
80
  Each new shape is automatically assigned the next color in the preset palette so overlapping shapes remain visually distinct. The shape editor includes a full color picker (identical to the signal color picker) for precise color control.
81
81
 
82
- <figure align="center">
83
- <img src="../../assets/user-guides/light-shapes-editor.jpg#only-light" alt="Shapes editor menu" style="width: 60%; height: auto;">
84
- <img src="../../assets/user-guides/dark-shapes-editor.jpg#only-dark" alt="Shapes editor menu" style="width: 60%; height: auto;">
82
+ <figure markdown="span">
83
+ ![Shapes editor menu](../../assets/user-guides/light-shapes-editor.jpg#only-light){ width="60%" height="auto" }
84
+ ![Shapes editor menu](../../assets/user-guides/dark-shapes-editor.jpg#only-dark){ width="60%" height="auto" }
85
85
  <figcaption>The menu for <b>shapes editor</b> is active and in editing mode. A shape's label and color is being edited. The plot area shows a vertical (yellow) and horizontal (red) line and a rectangle (purple).</figcaption>
86
86
  </figure>
87
87
 
@@ -115,9 +115,9 @@ Dojo provides a few basic export options to capture an image of the plot or save
115
115
  - **Filtered CSV:** A CSV file containing the data currently being plotted can be downloaded for a look at the raw data.
116
116
  - **Config JSON:** The current page configuration can be downloaded as a JSON so it can be reloaded at a later time.
117
117
 
118
- <figure align="center">
119
- <img src="../../assets/user-guides/light-export-options.jpg#only-light" alt="Export options menu" style="width: 60%; height: auto;">
120
- <img src="../../assets/user-guides/dark-export-options.jpg#only-dark" alt="Export options menu" style="width: 60%; height: auto;">
118
+ <figure markdown="span">
119
+ ![Export options menu](../../assets/user-guides/light-export-options.jpg#only-light){ width="60%" height="auto" }
120
+ ![Export options menu](../../assets/user-guides/dark-export-options.jpg#only-dark){ width="60%" height="auto" }
121
121
  <figcaption>The menu for <b>export options</b> is active. </figcaption>
122
122
  </figure>
123
123
 
@@ -15,7 +15,7 @@ In a standard Monte Carlo script, you use `mojo_model.sample_dist()` to represen
15
15
  Mojo supports two primary types of design variables within your generate script:
16
16
 
17
17
  - `DesignFloat`: For continuous parameters like spring stiffness, mass, or damping ratios.
18
- - `DesignCategorical`: For discrete choices like material types (['steel', 'aluminum']) or solver methods.
18
+ - `DesignCategorical`: For discrete choices like material types (`['steel', 'aluminum']`) or solver methods.
19
19
 
20
20
  ???+ example "Example: Defining Design Variables"
21
21
 
@@ -5,8 +5,8 @@
5
5
 
6
6
  The beauty of Mojo is that you don't need to manage the low-level MuJoCo physics state manually; the `RuntimeManager` handles the heavy lifting, ensuring your simulation is stable and your telemetry is perfectly synchronized.
7
7
 
8
- <figure align="center" class="fade-in">
9
- <img src="../../assets/user-guides/runtime-anim.gif" alt="Runtime final result" style="width: 50%; height: auto;">
8
+ <figure markdown="span">
9
+ ![Runtime final result](../../assets/user-guides/runtime-anim.gif){ width="50%" height="auto" }
10
10
  <figcaption>The visual result of the completed runtime script: Two spring forces act between the sphere site pairs defined in the generate step. The action-reaction forces are displayed. The boxes translate away from one another while rotating due to mismatched the unequal spring force.</figcaption>
11
11
  </figure>
12
12
 
@@ -145,7 +145,6 @@ plugins:
145
145
  - https://mkdocstrings.github.io/griffe/objects.inv
146
146
  - https://docs.pydantic.dev/latest/objects.inv
147
147
  - https://numpy.org/doc/stable/objects.inv
148
- - glightbox
149
148
 
150
149
  markdown_extensions:
151
150
  - abbr
@@ -187,10 +186,15 @@ markdown_extensions:
187
186
  - pymdownx.keys
188
187
  - pymdownx.mark
189
188
  - pymdownx.tilde
189
+ - zensical.extensions.glightbox:
190
+ auto_themed: true
190
191
 
191
192
  extra:
192
193
  generator: false
193
194
  social:
195
+ - icon: fontawesome/brands/python
196
+ link: https://pypi.org/project/mujoco-mojo/
197
+ name: PyPI
194
198
  - icon: fontawesome/brands/github
195
199
  link: https://github.com/Hydrowelder
196
200
  name: My GitHub
@@ -92,7 +92,7 @@ dev = [
92
92
  "ruff>=0.14.14",
93
93
  "tabulate>=0.9.0",
94
94
  "watchfiles>=1.1.1",
95
- "zensical>=0.0.31",
95
+ "zensical>=0.0.36",
96
96
  ]
97
97
 
98
98
  [project.scripts]
@@ -139,7 +139,11 @@ class MeshBase(XMLModel):
139
139
  @model_validator(mode="after")
140
140
  def validate_file(self) -> Self:
141
141
  # make the file extension lowercase
142
- if self.file is not None and self.file.suffix not in [".stl", ".msh", ".obj"]:
142
+ if self.file is not None and self.file.suffix.lower() not in [
143
+ ".stl",
144
+ ".msh",
145
+ ".obj",
146
+ ]:
143
147
  msg = f'Mesh {self.name}: Invalid file suffix ({self.file.suffix}). Must be ".stl", ".msh", or ".obj".'
144
148
  logger.error(msg)
145
149
  raise ValueError(msg)
@@ -211,7 +211,16 @@ class Inertial(XMLModel):
211
211
  eigvals = np.linalg.eigvalsh(M)
212
212
 
213
213
  if np.any(eigvals <= 0):
214
- msg = (f"Inertia matrix must be positive definite. Eigenvalues: {eigvals}",)
214
+ msg = f"Inertia matrix must be positive definite. Eigenvalues: {eigvals}"
215
+ logger.error(msg)
216
+ raise ValueError(msg)
217
+
218
+ # triangle inequality check
219
+ # eigvalsh returns eigenvalues in ascending order, so e1 + e3 >= e2 and
220
+ # e2 + e3 >= e1 always hold; only the largest-vs-sum-of-others case can fail
221
+ e1, e2, e3 = eigvals
222
+ if e1 + e2 < e3:
223
+ msg = f"Inertia tensor violates the triangle inequality: the largest principal moment of inertia ({e3:.6e}) exceeds the sum of the other two ({e1:.6e} + {e2:.6e} = {e1 + e2:.6e})."
215
224
  logger.error(msg)
216
225
  raise ValueError(msg)
217
226
 
@@ -429,6 +438,28 @@ class Inertial(XMLModel):
429
438
  logger.exception(msg)
430
439
  raise ValueError(msg)
431
440
 
441
+ def _seed_dist(input_val: Any) -> None:
442
+ """Update the seed and trial number for the distribution."""
443
+ if isinstance(input_val, (list, tuple)):
444
+ for item in input_val:
445
+ if isinstance(item, Distribution):
446
+ item.with_seed(mojo_model.seed).with_trial_num(
447
+ mojo_model.trial_num
448
+ )
449
+ elif isinstance(input_val, Distribution):
450
+ input_val.with_seed(mojo_model.seed).with_trial_num(
451
+ mojo_model.trial_num
452
+ )
453
+
454
+ _seed_dist(mass)
455
+ _seed_dist(pos)
456
+ if diaginertia is not None:
457
+ _seed_dist(diaginertia)
458
+ if fullinertia is not None:
459
+ _seed_dist(fullinertia)
460
+ if isinstance(orientation, tuple):
461
+ _seed_dist(orientation[1])
462
+
432
463
  def _resolve_and_track(input_val: Any) -> tuple[np.ndarray, list[NamedValue]]:
433
464
  """Samples distributions and prepares NamedValues for registration."""
434
465
  resolved_values = []
@@ -439,9 +470,6 @@ class Inertial(XMLModel):
439
470
  for item in input_val:
440
471
  if isinstance(item, Distribution):
441
472
  # sample raw, but create the NamedValue container
442
- item.with_seed(mojo_model.seed).with_trial_num(
443
- mojo_model.trial_num
444
- )
445
473
  nv = item.sample_to_named_value()
446
474
  resolved_values.append(nv.squeeze())
447
475
  pending_named_values.append(nv)
@@ -451,9 +479,6 @@ class Inertial(XMLModel):
451
479
 
452
480
  # case 2: single vector-level distribution
453
481
  if isinstance(input_val, Distribution):
454
- input_val.with_seed(mojo_model.seed).with_trial_num(
455
- mojo_model.trial_num
456
- )
457
482
  nv = input_val.sample_to_named_value()
458
483
  return nv.value.squeeze(), [nv]
459
484
 
@@ -64,3 +64,20 @@ class MojoModel(MojoBaseModel, StochasBase):
64
64
  self.user_data = cls.model_validate(data)
65
65
 
66
66
  return self.user_data
67
+
68
+ def clear_unpickleable_data(self) -> None:
69
+ """
70
+ Clear unpickleable objects from the model tree before serialization.
71
+
72
+ This walks through all geoms in the MJCF tree and clears cached collision managers and proximity queries that contain Cython objects which cannot be pickled for multiprocessing.
73
+ """
74
+ from mujoco_mojo.utils.proximity_mixin import ProximityMixin
75
+
76
+ if self.mjcf.worldbody is None:
77
+ return
78
+
79
+ bodies = self.mjcf.worldbody.walk_bodies(include_self=True)
80
+ for body in bodies:
81
+ for geom in body.geoms:
82
+ if isinstance(geom, ProximityMixin):
83
+ geom.clear_unpickleable()