Merge branch 'google-deepmind:main' into main

This commit is contained in:
Andrew Luo
2024-04-23 06:12:20 +02:00
committed by GitHub
43 changed files with 1757 additions and 1200 deletions
+902 -880
View File
File diff suppressed because it is too large Load Diff
+119 -117
View File
@@ -7,6 +7,42 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mujoco |br| |L| | | .. table:: | | mujoco |br| |L| | | .. table:: |
| :ref:`option | \* | :class: mjcf-attributes |
| <option>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`timestep<option-timestep>` | :ref:`apirate<option-apirate>` | :ref:`impratio<option-impratio>` | :ref:`tolerance<option-tolerance>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`ls_tolerance<option-ls_tolerance>` | :ref:`noslip_tolerance<option-noslip_tolerance>` | :ref:`mpr_tolerance<option-mpr_tolerance>` | :ref:`gravity<option-gravity>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`wind<option-wind>` | :ref:`magnetic<option-magnetic>` | :ref:`density<option-density>` | :ref:`viscosity<option-viscosity>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`o_margin<option-o_margin>` | :ref:`o_solref<option-o_solref>` | :ref:`o_solimp<option-o_solimp>` | :ref:`o_friction<option-o_friction>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`integrator<option-integrator>` | :ref:`cone<option-cone>` | :ref:`jacobian<option-jacobian>` | :ref:`solver<option-solver>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`iterations<option-iterations>` | :ref:`ls_iterations<option-ls_iterations>` | :ref:`noslip_iterations<option-noslip_iterations>` | :ref:`mpr_iterations<option-mpr_iterations>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`sdf_iterations<option-sdf_iterations>` | :ref:`sdf_initpoints<option-sdf_initpoints>` | :ref:`actuatorgroupdisable<option-actuatorgroupdisable>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| option |br| |_| |L| | | .. table:: |
| :ref:`flag | ? | :class: mjcf-attributes |
| <option-flag>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`constraint<option-flag-constraint>` | :ref:`equality<option-flag-equality>` | :ref:`frictionloss<option-flag-frictionloss>` | :ref:`limit<option-flag-limit>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`contact<option-flag-contact>` | :ref:`passive<option-flag-passive>` | :ref:`gravity<option-flag-gravity>` | :ref:`clampctrl<option-flag-clampctrl>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`warmstart<option-flag-warmstart>` | :ref:`filterparent<option-flag-filterparent>` | :ref:`actuation<option-flag-actuation>` | :ref:`refsafe<option-flag-refsafe>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`sensor<option-flag-sensor>` | :ref:`midphase<option-flag-midphase>` | :ref:`eulerdamp<option-flag-eulerdamp>` | :ref:`override<option-flag-override>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`energy<option-flag-energy>` | :ref:`fwdinv<option-flag-fwdinv>` | :ref:`invdiscrete<option-flag-invdiscrete>` | :ref:`multiccd<option-flag-multiccd>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`island<option-flag-island>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mujoco |br| |L| | | .. table:: |
| :ref:`compiler | \* | :class: mjcf-attributes | | :ref:`compiler | \* | :class: mjcf-attributes |
| <compiler>` | | | | <compiler>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
@@ -55,83 +91,6 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mujoco |br| |L| | | *no attributes* | | mujoco |br| |L| | | *no attributes* |
| :ref:`visual<visual>` | | |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| visual |br| |_| |L| | | .. table:: |
| :ref:`global | ? | :class: mjcf-attributes |
| <visual-global>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`fovy<visual-global-fovy>` | :ref:`ipd<visual-global-ipd>` | :ref:`azimuth<visual-global-azimuth>` | :ref:`elevation<visual-global-elevation>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`linewidth<visual-global-linewidth>` | :ref:`glow<visual-global-glow>` | :ref:`offwidth<visual-global-offwidth>` | :ref:`offheight<visual-global-offheight>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`realtime<visual-global-realtime>` | :ref:`ellipsoidinertia<visual-global-ellipsoidinertia>` | :ref:`bvactive<visual-global-bvactive>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| visual |br| |_| |L| | | .. table:: |
| :ref:`quality | ? | :class: mjcf-attributes |
| <visual-quality>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`shadowsize<visual-quality-shadowsize>` | :ref:`offsamples<visual-quality-offsamples>` | :ref:`numslices<visual-quality-numslices>` | :ref:`numstacks<visual-quality-numstacks>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`numquads<visual-quality-numquads>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| visual |br| |_| |L| | | .. table:: |
| :ref:`headlight | ? | :class: mjcf-attributes |
| <visual-headlight>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`ambient<visual-headlight-ambient>` | :ref:`diffuse<visual-headlight-diffuse>` | :ref:`specular<visual-headlight-specular>` | :ref:`active<visual-headlight-active>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| visual |br| |_| |L| | | .. table:: |
| :ref:`map | ? | :class: mjcf-attributes |
| <visual-map>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`stiffness<visual-map-stiffness>` | :ref:`stiffnessrot<visual-map-stiffnessrot>` | :ref:`force<visual-map-force>` | :ref:`torque<visual-map-torque>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`alpha<visual-map-alpha>` | :ref:`fogstart<visual-map-fogstart>` | :ref:`fogend<visual-map-fogend>` | :ref:`znear<visual-map-znear>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`zfar<visual-map-zfar>` | :ref:`haze<visual-map-haze>` | :ref:`shadowclip<visual-map-shadowclip>` | :ref:`shadowscale<visual-map-shadowscale>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`actuatortendon<visual-map-actuatortendon>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| visual |br| |_| |L| | | .. table:: |
| :ref:`scale | ? | :class: mjcf-attributes |
| <visual-scale>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`forcewidth<visual-scale-forcewidth>` | :ref:`contactwidth<visual-scale-contactwidth>` | :ref:`contactheight<visual-scale-contactheight>` | :ref:`connect<visual-scale-connect>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`com<visual-scale-com>` | :ref:`camera<visual-scale-camera>` | :ref:`light<visual-scale-light>` | :ref:`selectpoint<visual-scale-selectpoint>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`jointlength<visual-scale-jointlength>` | :ref:`jointwidth<visual-scale-jointwidth>` | :ref:`actuatorlength<visual-scale-actuatorlength>` | :ref:`actuatorwidth<visual-scale-actuatorwidth>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`framelength<visual-scale-framelength>` | :ref:`framewidth<visual-scale-framewidth>` | :ref:`constraint<visual-scale-constraint>` | :ref:`slidercrank<visual-scale-slidercrank>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`frustum<visual-scale-frustum>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| visual |br| |_| |L| | | .. table:: |
| :ref:`rgba | ? | :class: mjcf-attributes |
| <visual-rgba>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`fog<visual-rgba-fog>` | :ref:`haze<visual-rgba-haze>` | :ref:`force<visual-rgba-force>` | :ref:`inertia<visual-rgba-inertia>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`joint<visual-rgba-joint>` | :ref:`actuator<visual-rgba-actuator>` | :ref:`actuatornegative<visual-rgba-actuatornegative>` | :ref:`actuatorpositive<visual-rgba-actuatorpositive>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`com<visual-rgba-com>` | :ref:`camera<visual-rgba-camera>` | :ref:`light<visual-rgba-light>` | :ref:`selectpoint<visual-rgba-selectpoint>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`connect<visual-rgba-connect>` | :ref:`contactpoint<visual-rgba-contactpoint>` | :ref:`contactforce<visual-rgba-contactforce>` | :ref:`contactfriction<visual-rgba-contactfriction>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`contacttorque<visual-rgba-contacttorque>` | :ref:`contactgap<visual-rgba-contactgap>` | :ref:`rangefinder<visual-rgba-rangefinder>` | :ref:`constraint<visual-rgba-constraint>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`slidercrank<visual-rgba-slidercrank>` | :ref:`crankbroken<visual-rgba-crankbroken>` | :ref:`frustum<visual-rgba-frustum>` | :ref:`bv<visual-rgba-bv>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`bvactive<visual-rgba-bvactive>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mujoco |br| |L| | | *no attributes* |
| :ref:`asset<asset>` | | | | :ref:`asset<asset>` | | |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| asset |br| |_| |L| | | .. table:: | | |_| asset |br| |_| |L| | | .. table:: |
@@ -213,43 +172,7 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`texuniform<asset-material-texuniform>` | :ref:`emission<asset-material-emission>` | :ref:`specular<asset-material-specular>` | :ref:`shininess<asset-material-shininess>` | | | | | | :ref:`texuniform<asset-material-texuniform>` | :ref:`emission<asset-material-emission>` | :ref:`specular<asset-material-specular>` | :ref:`shininess<asset-material-shininess>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`reflectance<asset-material-reflectance>` | :ref:`rgba<asset-material-rgba>` | | | | | | | | :ref:`reflectance<asset-material-reflectance>` | :ref:`metallic<asset-material-metallic>` | :ref:`roughness<asset-material-roughness>` | :ref:`rgba<asset-material-rgba>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mujoco |br| |L| | | .. table:: |
| :ref:`option | \* | :class: mjcf-attributes |
| <option>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`timestep<option-timestep>` | :ref:`apirate<option-apirate>` | :ref:`impratio<option-impratio>` | :ref:`tolerance<option-tolerance>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`ls_tolerance<option-ls_tolerance>` | :ref:`noslip_tolerance<option-noslip_tolerance>` | :ref:`mpr_tolerance<option-mpr_tolerance>` | :ref:`gravity<option-gravity>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`wind<option-wind>` | :ref:`magnetic<option-magnetic>` | :ref:`density<option-density>` | :ref:`viscosity<option-viscosity>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`o_margin<option-o_margin>` | :ref:`o_solref<option-o_solref>` | :ref:`o_solimp<option-o_solimp>` | :ref:`o_friction<option-o_friction>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`integrator<option-integrator>` | :ref:`cone<option-cone>` | :ref:`jacobian<option-jacobian>` | :ref:`solver<option-solver>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`iterations<option-iterations>` | :ref:`ls_iterations<option-ls_iterations>` | :ref:`noslip_iterations<option-noslip_iterations>` | :ref:`mpr_iterations<option-mpr_iterations>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`sdf_iterations<option-sdf_iterations>` | :ref:`sdf_initpoints<option-sdf_initpoints>` | :ref:`actuatorgroupdisable<option-actuatorgroupdisable>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| option |br| |_| |L| | | .. table:: |
| :ref:`flag | ? | :class: mjcf-attributes |
| <option-flag>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`constraint<option-flag-constraint>` | :ref:`equality<option-flag-equality>` | :ref:`frictionloss<option-flag-frictionloss>` | :ref:`limit<option-flag-limit>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`contact<option-flag-contact>` | :ref:`passive<option-flag-passive>` | :ref:`gravity<option-flag-gravity>` | :ref:`clampctrl<option-flag-clampctrl>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`warmstart<option-flag-warmstart>` | :ref:`filterparent<option-flag-filterparent>` | :ref:`actuation<option-flag-actuation>` | :ref:`refsafe<option-flag-refsafe>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`sensor<option-flag-sensor>` | :ref:`midphase<option-flag-midphase>` | :ref:`eulerdamp<option-flag-eulerdamp>` | :ref:`override<option-flag-override>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`energy<option-flag-energy>` | :ref:`fwdinv<option-flag-fwdinv>` | :ref:`invdiscrete<option-flag-invdiscrete>` | :ref:`multiccd<option-flag-multiccd>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`island<option-flag-island>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mujoco |br| |L| | | .. table:: | | mujoco |br| |L| | | .. table:: |
@@ -369,7 +292,7 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`name<body-light-name>` | :ref:`class<body-light-class>` | :ref:`directional<body-light-directional>` | :ref:`castshadow<body-light-castshadow>` | | | | | | :ref:`name<body-light-name>` | :ref:`class<body-light-class>` | :ref:`directional<body-light-directional>` | :ref:`castshadow<body-light-castshadow>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`active<body-light-active>` | :ref:`pos<body-light-pos>` | :ref:`dir<body-light-dir>` | :ref:`radius<body-light-radius>` | | | | | | :ref:`active<body-light-active>` | :ref:`pos<body-light-pos>` | :ref:`dir<body-light-dir>` | :ref:`bulbradius<body-light-bulbradius>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`attenuation<body-light-attenuation>` | :ref:`cutoff<body-light-cutoff>` | :ref:`exponent<body-light-exponent>` | :ref:`ambient<body-light-ambient>` | | | | | | :ref:`attenuation<body-light-attenuation>` | :ref:`cutoff<body-light-cutoff>` | :ref:`exponent<body-light-exponent>` | :ref:`ambient<body-light-ambient>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
@@ -1287,6 +1210,83 @@
| | | | :ref:`act<keyframe-key-act>` | :ref:`mpos<keyframe-key-mpos>` | :ref:`mquat<keyframe-key-mquat>` | :ref:`ctrl<keyframe-key-ctrl>` | | | | | | :ref:`act<keyframe-key-act>` | :ref:`mpos<keyframe-key-mpos>` | :ref:`mquat<keyframe-key-mquat>` | :ref:`ctrl<keyframe-key-ctrl>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mujoco |br| |L| | | *no attributes* |
| :ref:`visual<visual>` | | |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| visual |br| |_| |L| | | .. table:: |
| :ref:`global | ? | :class: mjcf-attributes |
| <visual-global>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`fovy<visual-global-fovy>` | :ref:`ipd<visual-global-ipd>` | :ref:`azimuth<visual-global-azimuth>` | :ref:`elevation<visual-global-elevation>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`linewidth<visual-global-linewidth>` | :ref:`glow<visual-global-glow>` | :ref:`offwidth<visual-global-offwidth>` | :ref:`offheight<visual-global-offheight>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`realtime<visual-global-realtime>` | :ref:`ellipsoidinertia<visual-global-ellipsoidinertia>` | :ref:`bvactive<visual-global-bvactive>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| visual |br| |_| |L| | | .. table:: |
| :ref:`quality | ? | :class: mjcf-attributes |
| <visual-quality>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`shadowsize<visual-quality-shadowsize>` | :ref:`offsamples<visual-quality-offsamples>` | :ref:`numslices<visual-quality-numslices>` | :ref:`numstacks<visual-quality-numstacks>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`numquads<visual-quality-numquads>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| visual |br| |_| |L| | | .. table:: |
| :ref:`headlight | ? | :class: mjcf-attributes |
| <visual-headlight>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`ambient<visual-headlight-ambient>` | :ref:`diffuse<visual-headlight-diffuse>` | :ref:`specular<visual-headlight-specular>` | :ref:`active<visual-headlight-active>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| visual |br| |_| |L| | | .. table:: |
| :ref:`map | ? | :class: mjcf-attributes |
| <visual-map>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`stiffness<visual-map-stiffness>` | :ref:`stiffnessrot<visual-map-stiffnessrot>` | :ref:`force<visual-map-force>` | :ref:`torque<visual-map-torque>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`alpha<visual-map-alpha>` | :ref:`fogstart<visual-map-fogstart>` | :ref:`fogend<visual-map-fogend>` | :ref:`znear<visual-map-znear>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`zfar<visual-map-zfar>` | :ref:`haze<visual-map-haze>` | :ref:`shadowclip<visual-map-shadowclip>` | :ref:`shadowscale<visual-map-shadowscale>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`actuatortendon<visual-map-actuatortendon>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| visual |br| |_| |L| | | .. table:: |
| :ref:`scale | ? | :class: mjcf-attributes |
| <visual-scale>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`forcewidth<visual-scale-forcewidth>` | :ref:`contactwidth<visual-scale-contactwidth>` | :ref:`contactheight<visual-scale-contactheight>` | :ref:`connect<visual-scale-connect>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`com<visual-scale-com>` | :ref:`camera<visual-scale-camera>` | :ref:`light<visual-scale-light>` | :ref:`selectpoint<visual-scale-selectpoint>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`jointlength<visual-scale-jointlength>` | :ref:`jointwidth<visual-scale-jointwidth>` | :ref:`actuatorlength<visual-scale-actuatorlength>` | :ref:`actuatorwidth<visual-scale-actuatorwidth>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`framelength<visual-scale-framelength>` | :ref:`framewidth<visual-scale-framewidth>` | :ref:`constraint<visual-scale-constraint>` | :ref:`slidercrank<visual-scale-slidercrank>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`frustum<visual-scale-frustum>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| visual |br| |_| |L| | | .. table:: |
| :ref:`rgba | ? | :class: mjcf-attributes |
| <visual-rgba>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`fog<visual-rgba-fog>` | :ref:`haze<visual-rgba-haze>` | :ref:`force<visual-rgba-force>` | :ref:`inertia<visual-rgba-inertia>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`joint<visual-rgba-joint>` | :ref:`actuator<visual-rgba-actuator>` | :ref:`actuatornegative<visual-rgba-actuatornegative>` | :ref:`actuatorpositive<visual-rgba-actuatorpositive>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`com<visual-rgba-com>` | :ref:`camera<visual-rgba-camera>` | :ref:`light<visual-rgba-light>` | :ref:`selectpoint<visual-rgba-selectpoint>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`connect<visual-rgba-connect>` | :ref:`contactpoint<visual-rgba-contactpoint>` | :ref:`contactforce<visual-rgba-contactforce>` | :ref:`contactfriction<visual-rgba-contactfriction>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`contacttorque<visual-rgba-contacttorque>` | :ref:`contactgap<visual-rgba-contactgap>` | :ref:`rangefinder<visual-rgba-rangefinder>` | :ref:`constraint<visual-rgba-constraint>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`slidercrank<visual-rgba-slidercrank>` | :ref:`crankbroken<visual-rgba-crankbroken>` | :ref:`frustum<visual-rgba-frustum>` | :ref:`bv<visual-rgba-bv>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`bvactive<visual-rgba-bvactive>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mujoco |br| |L| | | .. table:: | | mujoco |br| |L| | | .. table:: |
| :ref:`default | R | :class: mjcf-attributes | | :ref:`default | R | :class: mjcf-attributes |
| <default>` | | | | <default>` | | |
@@ -1307,7 +1307,9 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`texture<default-material-texture>` | :ref:`emission<default-material-emission>` | :ref:`specular<default-material-specular>` | :ref:`shininess<default-material-shininess>` | | | | | | :ref:`texture<default-material-texture>` | :ref:`emission<default-material-emission>` | :ref:`specular<default-material-specular>` | :ref:`shininess<default-material-shininess>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`reflectance<default-material-reflectance>` | :ref:`rgba<default-material-rgba>` | :ref:`texrepeat<default-material-texrepeat>` | :ref:`texuniform<default-material-texuniform>` | | | | | | :ref:`reflectance<default-material-reflectance>` | :ref:`metallic<default-material-metallic>` | :ref:`roughness<default-material-roughness>` | :ref:`rgba<default-material-rgba>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`texrepeat<default-material-texrepeat>` | :ref:`texuniform<default-material-texuniform>` | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| default |br| |_| |L| | | .. table:: | | |_| default |br| |_| |L| | | .. table:: |
@@ -1378,7 +1380,7 @@
| :ref:`light | ? | :class: mjcf-attributes | | :ref:`light | ? | :class: mjcf-attributes |
| <default-light>` | | | | <default-light>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`pos<default-light-pos>` | :ref:`dir<default-light-dir>` | :ref:`radius<default-light-radius>` | :ref:`directional<default-light-directional>` | | | | | | :ref:`pos<default-light-pos>` | :ref:`dir<default-light-dir>` | :ref:`bulbradius<default-light-bulbradius>` | :ref:`directional<default-light-directional>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`castshadow<default-light-castshadow>` | :ref:`active<default-light-active>` | :ref:`attenuation<default-light-attenuation>` | :ref:`cutoff<default-light-cutoff>` | | | | | | :ref:`castshadow<default-light-castshadow>` | :ref:`active<default-light-active>` | :ref:`attenuation<default-light-attenuation>` | :ref:`cutoff<default-light-cutoff>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+23 -14
View File
@@ -9,35 +9,44 @@ General
^^^^^^^ ^^^^^^^
1. Added ``mjModel.mesh_scale``: the scaling applied to asset vertices, as specified in the 1. Added ``mjModel.mesh_scale``: the scaling applied to asset vertices, as specified in the
:ref:`scale<asset-mesh-scale>` attribute. :ref:`scale<asset-mesh-scale>` attribute.
2. Added the :ref:`light/radius<body-light-radius>` attribute and corresponding ``mjModel.light_radius`` field. This 2. Added visual properties which are ignored by the native renderer, but can be used by external renderers:
value has no effect in MuJoCo's native renderer, but can be usful when rendering scenes with an external renderer.
- :ref:`light/bulbradius<body-light-bulbradius>` attribute and corresponding ``mjModel.light_bulbradius`` field.
- :ref:`material/metallic<asset-material-metallic>` attribute and corresponding ``mjModel.material_metallic`` field.
- :ref:`material/roughness<asset-material-roughness>` attribute and corresponding ``mjModel.material_roughness``
field.
3. The type of the ``size`` argument of :ref:`mj_stackAllocNum` and :ref:`mj_stackAllocInt` was changed from ``int``
to ``size_t``.
MJX MJX
^^^ ^^^
.. admonition:: Breaking API changes .. admonition:: Breaking API changes
:class: attention :class: attention
3. Removed deprecated ``mjx.device_get_into`` and ``mjx.device_put`` functions as they lack critical new 4. Removed deprecated ``mjx.device_get_into`` and ``mjx.device_put`` functions as they lack critical new
functionality. functionality.
**Migration:** Use ``mjx.get_data_into`` instead of ``mjx.device_get_into``, and ``mjx.put_data`` instead of **Migration:** Use ``mjx.get_data_into`` instead of ``mjx.device_get_into``, and ``mjx.put_data`` instead of
``mjx.device_put``. ``mjx.device_put``.
4. Added cylinder plane collisions. 5. Added cylinder plane collisions.
5. Added ``efc_type`` to ``mjx.Data`` and ``dim``, ``efc_address`` to ``mjx.Contact``. 6. Added ``efc_type`` to ``mjx.Data`` and ``dim``, ``efc_address`` to ``mjx.Contact``.
6. Added ``geom`` to ``mjx.Contact`` and marked ``geom1``, ``geom2`` deprecated. 7. Added ``geom`` to ``mjx.Contact`` and marked ``geom1``, ``geom2`` deprecated.
7. Added ``ne``, ``nf``, ``nl``, ``nefc``, and ``ncon`` to ``mjx.Data`` to match ``mujoco.MjData``. 8. Added ``ne``, ``nf``, ``nl``, ``nefc``, and ``ncon`` to ``mjx.Data`` to match ``mujoco.MjData``.
8. Given the above added fields, removed ``mjx.get_params``, ``mjx.ncon``, and ``mjx.count_constraints``. 9. Given the above added fields, removed ``mjx.get_params``, ``mjx.ncon``, and ``mjx.count_constraints``.
9. Changed the way meshes are organized on device to speed up collision detection when a mesh is replicated for many 10. Changed the way meshes are organized on device to speed up collision detection when a mesh is replicated for many
geoms. geoms.
10. Fixed a bug where capsules might be ignored in broadphase colliision checking. 11. Fixed a bug where capsules might be ignored in broadphase colliision checking.
12. Added cylinder collisions using SDFs.
13. Added support for all :ref:`condim <coContact>`: 1, 3, 4, 6.
Bug fixes Bug fixes
^^^^^^^^^ ^^^^^^^^^
11. Defaults of lights were not being saved, now fixed. 14. Defaults of lights were not being saved, now fixed.
12. Prevent overwriting of frame names by body names when saving an XML. Introduced in 3.1.4. 15. Prevent overwriting of frame names by body names when saving an XML. Bug introduced in 3.1.4.
13. Fixed bug in Python binding of :ref:`mj_saveModel`: ``buffer`` argument was documented as optional but was actually 16. Fixed bug in Python binding of :ref:`mj_saveModel`: ``buffer`` argument was documented as optional but was actually
not optional. not optional.
16. Fixed bug that prevented memory allocations larger than 2.15 GB.
Version 3.1.4 (April 10th, 2024) Version 3.1.4 (April 10th, 2024)
+10 -3
View File
@@ -922,6 +922,7 @@ struct mjModel_ {
int nD; // number of non-zeros in sparse dof-dof matrix int nD; // number of non-zeros in sparse dof-dof matrix
int nB; // number of non-zeros in sparse body-dof matrix int nB; // number of non-zeros in sparse body-dof matrix
int ntree; // number of kinematic trees under world body int ntree; // number of kinematic trees under world body
int ngravcomp; // number of bodies with nonzero gravcomp
int nemax; // number of potential equality-constraint rows int nemax; // number of potential equality-constraint rows
int njmax; // number of available rows in constraint Jacobian int njmax; // number of available rows in constraint Jacobian
int nconmax; // number of potential contacts in contact list int nconmax; // number of potential contacts in contact list
@@ -1079,10 +1080,10 @@ struct mjModel_ {
int* light_targetbodyid; // id of targeted body; -1: none (nlight x 1) int* light_targetbodyid; // id of targeted body; -1: none (nlight x 1)
mjtByte* light_directional; // directional light (nlight x 1) mjtByte* light_directional; // directional light (nlight x 1)
mjtByte* light_castshadow; // does light cast shadows (nlight x 1) mjtByte* light_castshadow; // does light cast shadows (nlight x 1)
float* light_bulbradius; // light radius for soft shadows (nlight x 1)
mjtByte* light_active; // is light on (nlight x 1) mjtByte* light_active; // is light on (nlight x 1)
mjtNum* light_pos; // position rel. to body frame (nlight x 3) mjtNum* light_pos; // position rel. to body frame (nlight x 3)
mjtNum* light_dir; // direction rel. to body frame (nlight x 3) mjtNum* light_dir; // direction rel. to body frame (nlight x 3)
mjtNum* light_radius; // radius of the light (nlight x 1)
mjtNum* light_poscom0; // global position rel. to sub-com in qpos0 (nlight x 3) mjtNum* light_poscom0; // global position rel. to sub-com in qpos0 (nlight x 3)
mjtNum* light_pos0; // global position rel. to body in qpos0 (nlight x 3) mjtNum* light_pos0; // global position rel. to body in qpos0 (nlight x 3)
mjtNum* light_dir0; // global direction in qpos0 (nlight x 3) mjtNum* light_dir0; // global direction in qpos0 (nlight x 3)
@@ -1219,6 +1220,8 @@ struct mjModel_ {
float* mat_specular; // specular (x white) (nmat x 1) float* mat_specular; // specular (x white) (nmat x 1)
float* mat_shininess; // shininess coef (nmat x 1) float* mat_shininess; // shininess coef (nmat x 1)
float* mat_reflectance; // reflectance (0: disable) (nmat x 1) float* mat_reflectance; // reflectance (0: disable) (nmat x 1)
float* mat_metallic; // metallic coef (nmat x 1)
float* mat_roughness; // roughness coef (nmat x 1)
float* mat_rgba; // rgba (nmat x 4) float* mat_rgba; // rgba (nmat x 4)
// predefined geom pairs for collision detection; has precedence over exclude // predefined geom pairs for collision detection; has precedence over exclude
@@ -2022,6 +2025,7 @@ struct mjvLight_ { // OpenGL light
mjtByte headlight; // headlight mjtByte headlight; // headlight
mjtByte directional; // directional light mjtByte directional; // directional light
mjtByte castshadow; // does light cast shadows mjtByte castshadow; // does light cast shadows
float bulbradius; // bulb radius for soft shadows
}; };
typedef struct mjvLight_ mjvLight; typedef struct mjvLight_ mjvLight;
struct mjvOption_ { // abstract visualization options struct mjvOption_ { // abstract visualization options
@@ -2236,6 +2240,7 @@ struct mjvSceneState_ {
mjtByte* light_directional; mjtByte* light_directional;
mjtByte* light_castshadow; mjtByte* light_castshadow;
float* light_bulbradius;
mjtByte* light_active; mjtByte* light_active;
float* light_attenuation; float* light_attenuation;
float* light_cutoff; float* light_cutoff;
@@ -2303,6 +2308,8 @@ struct mjvSceneState_ {
float* mat_specular; float* mat_specular;
float* mat_shininess; float* mat_shininess;
float* mat_reflectance; float* mat_reflectance;
float* mat_metallic;
float* mat_roughness;
float* mat_rgba; float* mat_rgba;
int* eq_type; int* eq_type;
@@ -2447,8 +2454,8 @@ void mj_resetDataKeyframe(const mjModel* m, mjData* d, int key);
void mj_markStack(mjData* d); void mj_markStack(mjData* d);
void mj_freeStack(mjData* d); void mj_freeStack(mjData* d);
void* mj_stackAllocByte(mjData* d, size_t bytes, size_t alignment); void* mj_stackAllocByte(mjData* d, size_t bytes, size_t alignment);
mjtNum* mj_stackAllocNum(mjData* d, int size); mjtNum* mj_stackAllocNum(mjData* d, size_t size);
int* mj_stackAllocInt(mjData* d, int size); int* mj_stackAllocInt(mjData* d, size_t size);
void mj_deleteData(mjData* d); void mj_deleteData(mjData* d);
void mj_resetCallbacks(void); void mj_resetCallbacks(void);
void mj_setConst(mjModel* m, mjData* d); void mj_setConst(mjModel* m, mjData* d);
+3 -5
View File
@@ -191,7 +191,7 @@ The following features are **fully supported** in MJX:
* - :ref:`Geom <mjtGeom>` * - :ref:`Geom <mjtGeom>`
- ``PLANE``, ``SPHERE``, ``CAPSULE``, ``BOX``, ``MESH`` - ``PLANE``, ``SPHERE``, ``CAPSULE``, ``BOX``, ``MESH``
* - :ref:`Constraint <mjtConstraint>` * - :ref:`Constraint <mjtConstraint>`
- ``EQUALITY``, ``LIMIT_JOINT``, ``CONTACT_PYRAMIDAL`` - ``EQUALITY``, ``LIMIT_JOINT``, ``CONTACT_FRICTIONLESS``, ``CONTACT_PYRAMIDAL``
* - :ref:`Equality <mjtEq>` * - :ref:`Equality <mjtEq>`
- ``CONNECT``, ``WELD``, ``JOINT`` - ``CONNECT``, ``WELD``, ``JOINT``
* - :ref:`Integrator <mjtIntegrator>` * - :ref:`Integrator <mjtIntegrator>`
@@ -199,7 +199,7 @@ The following features are **fully supported** in MJX:
* - :ref:`Cone <mjtCone>` * - :ref:`Cone <mjtCone>`
- ``PYRAMIDAL`` - ``PYRAMIDAL``
* - :ref:`Condim <coContact>` * - :ref:`Condim <coContact>`
- 3 - 1, 3, 4, 6
* - :ref:`Solver <mjtSolver>` * - :ref:`Solver <mjtSolver>`
- ``CG``, ``NEWTON`` - ``CG``, ``NEWTON``
* - Fluid Model * - Fluid Model
@@ -217,10 +217,8 @@ The following features are **in development** and coming soon:
- Feature - Feature
* - :ref:`Geom <mjtGeom>` * - :ref:`Geom <mjtGeom>`
- ``SDF``, ``HFIELD``, ``ELLIPSOID``, ``CYLINDER`` - ``SDF``, ``HFIELD``, ``ELLIPSOID``, ``CYLINDER``
* - :ref:`Condim <coContact>`
- 1, 4, 6
* - :ref:`Constraint <mjtConstraint>` * - :ref:`Constraint <mjtConstraint>`
- :ref:`Frictionloss <coFriction>`, ``CONTACT_FRICTIONLESS``, ``CONTACT_ELLIPTIC``, ``FRICTION_DOF`` - :ref:`Frictionloss <coFriction>`, ``CONTACT_ELLIPTIC``, ``FRICTION_DOF``
* - :ref:`Integrator <mjtIntegrator>` * - :ref:`Integrator <mjtIntegrator>`
- ``IMPLICIT``, ``IMPLICITFAST`` - ``IMPLICIT``, ``IMPLICITFAST``
* - Dynamics * - Dynamics
+4 -1
View File
@@ -637,6 +637,7 @@ struct mjModel_ {
int nD; // number of non-zeros in sparse dof-dof matrix int nD; // number of non-zeros in sparse dof-dof matrix
int nB; // number of non-zeros in sparse body-dof matrix int nB; // number of non-zeros in sparse body-dof matrix
int ntree; // number of kinematic trees under world body int ntree; // number of kinematic trees under world body
int ngravcomp; // number of bodies with nonzero gravcomp
int nemax; // number of potential equality-constraint rows int nemax; // number of potential equality-constraint rows
int njmax; // number of available rows in constraint Jacobian int njmax; // number of available rows in constraint Jacobian
int nconmax; // number of potential contacts in contact list int nconmax; // number of potential contacts in contact list
@@ -794,10 +795,10 @@ struct mjModel_ {
int* light_targetbodyid; // id of targeted body; -1: none (nlight x 1) int* light_targetbodyid; // id of targeted body; -1: none (nlight x 1)
mjtByte* light_directional; // directional light (nlight x 1) mjtByte* light_directional; // directional light (nlight x 1)
mjtByte* light_castshadow; // does light cast shadows (nlight x 1) mjtByte* light_castshadow; // does light cast shadows (nlight x 1)
float* light_bulbradius; // light radius for soft shadows (nlight x 1)
mjtByte* light_active; // is light on (nlight x 1) mjtByte* light_active; // is light on (nlight x 1)
mjtNum* light_pos; // position rel. to body frame (nlight x 3) mjtNum* light_pos; // position rel. to body frame (nlight x 3)
mjtNum* light_dir; // direction rel. to body frame (nlight x 3) mjtNum* light_dir; // direction rel. to body frame (nlight x 3)
mjtNum* light_radius; // radius of the light (nlight x 1)
mjtNum* light_poscom0; // global position rel. to sub-com in qpos0 (nlight x 3) mjtNum* light_poscom0; // global position rel. to sub-com in qpos0 (nlight x 3)
mjtNum* light_pos0; // global position rel. to body in qpos0 (nlight x 3) mjtNum* light_pos0; // global position rel. to body in qpos0 (nlight x 3)
mjtNum* light_dir0; // global direction in qpos0 (nlight x 3) mjtNum* light_dir0; // global direction in qpos0 (nlight x 3)
@@ -934,6 +935,8 @@ struct mjModel_ {
float* mat_specular; // specular (x white) (nmat x 1) float* mat_specular; // specular (x white) (nmat x 1)
float* mat_shininess; // shininess coef (nmat x 1) float* mat_shininess; // shininess coef (nmat x 1)
float* mat_reflectance; // reflectance (0: disable) (nmat x 1) float* mat_reflectance; // reflectance (0: disable) (nmat x 1)
float* mat_metallic; // metallic coef (nmat x 1)
float* mat_roughness; // roughness coef (nmat x 1)
float* mat_rgba; // rgba (nmat x 4) float* mat_rgba; // rgba (nmat x 4)
// predefined geom pairs for collision detection; has precedence over exclude // predefined geom pairs for collision detection; has precedence over exclude
+4
View File
@@ -263,6 +263,7 @@ struct mjvLight_ { // OpenGL light
mjtByte headlight; // headlight mjtByte headlight; // headlight
mjtByte directional; // directional light mjtByte directional; // directional light
mjtByte castshadow; // does light cast shadows mjtByte castshadow; // does light cast shadows
float bulbradius; // bulb radius for soft shadows
}; };
typedef struct mjvLight_ mjvLight; typedef struct mjvLight_ mjvLight;
@@ -493,6 +494,7 @@ struct mjvSceneState_ {
mjtByte* light_directional; mjtByte* light_directional;
mjtByte* light_castshadow; mjtByte* light_castshadow;
float* light_bulbradius;
mjtByte* light_active; mjtByte* light_active;
float* light_attenuation; float* light_attenuation;
float* light_cutoff; float* light_cutoff;
@@ -560,6 +562,8 @@ struct mjvSceneState_ {
float* mat_specular; float* mat_specular;
float* mat_shininess; float* mat_shininess;
float* mat_reflectance; float* mat_reflectance;
float* mat_metallic;
float* mat_roughness;
float* mat_rgba; float* mat_rgba;
int* eq_type; int* eq_type;
+4 -1
View File
@@ -139,6 +139,7 @@
X ( njmax ) \ X ( njmax ) \
X ( nconmax ) \ X ( nconmax ) \
XMJV( ntree ) \ XMJV( ntree ) \
X ( ngravcomp ) \
X ( nuserdata ) \ X ( nuserdata ) \
XMJV( nsensordata ) \ XMJV( nsensordata ) \
X ( npluginstate ) \ X ( npluginstate ) \
@@ -292,10 +293,10 @@
X ( int, light_targetbodyid, nlight, 1 ) \ X ( int, light_targetbodyid, nlight, 1 ) \
XMJV( mjtByte, light_directional, nlight, 1 ) \ XMJV( mjtByte, light_directional, nlight, 1 ) \
XMJV( mjtByte, light_castshadow, nlight, 1 ) \ XMJV( mjtByte, light_castshadow, nlight, 1 ) \
XMJV( float, light_bulbradius, nlight, 1 ) \
XMJV( mjtByte, light_active, nlight, 1 ) \ XMJV( mjtByte, light_active, nlight, 1 ) \
X ( mjtNum, light_pos, nlight, 3 ) \ X ( mjtNum, light_pos, nlight, 3 ) \
X ( mjtNum, light_dir, nlight, 3 ) \ X ( mjtNum, light_dir, nlight, 3 ) \
X ( mjtNum, light_radius, nlight, 1 ) \
X ( mjtNum, light_poscom0, nlight, 3 ) \ X ( mjtNum, light_poscom0, nlight, 3 ) \
X ( mjtNum, light_pos0, nlight, 3 ) \ X ( mjtNum, light_pos0, nlight, 3 ) \
X ( mjtNum, light_dir0, nlight, 3 ) \ X ( mjtNum, light_dir0, nlight, 3 ) \
@@ -418,6 +419,8 @@
XMJV( float, mat_specular, nmat, 1 ) \ XMJV( float, mat_specular, nmat, 1 ) \
XMJV( float, mat_shininess, nmat, 1 ) \ XMJV( float, mat_shininess, nmat, 1 ) \
XMJV( float, mat_reflectance, nmat, 1 ) \ XMJV( float, mat_reflectance, nmat, 1 ) \
XMJV( float, mat_metallic, nmat, 1 ) \
XMJV( float, mat_roughness, nmat, 1 ) \
XMJV( float, mat_rgba, nmat, 4 ) \ XMJV( float, mat_rgba, nmat, 4 ) \
X ( int, pair_dim, npair, 1 ) \ X ( int, pair_dim, npair, 1 ) \
X ( int, pair_geom1, npair, 1 ) \ X ( int, pair_geom1, npair, 1 ) \
+2 -2
View File
@@ -203,10 +203,10 @@ MJAPI void mj_freeStack(mjData* d);
MJAPI void* mj_stackAllocByte(mjData* d, size_t bytes, size_t alignment); MJAPI void* mj_stackAllocByte(mjData* d, size_t bytes, size_t alignment);
// Allocate array of mjtNums on mjData stack. Call mju_error on stack overflow. // Allocate array of mjtNums on mjData stack. Call mju_error on stack overflow.
MJAPI mjtNum* mj_stackAllocNum(mjData* d, int size); MJAPI mjtNum* mj_stackAllocNum(mjData* d, size_t size);
// Allocate array of ints on mjData stack. Call mju_error on stack overflow. // Allocate array of ints on mjData stack. Call mju_error on stack overflow.
MJAPI int* mj_stackAllocInt(mjData* d, int size); MJAPI int* mj_stackAllocInt(mjData* d, size_t size);
// Free memory allocation in mjData. // Free memory allocation in mjData.
MJAPI void mj_deleteData(mjData* d); MJAPI void mj_deleteData(mjData* d);
+2 -2
View File
@@ -774,7 +774,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
), ),
FunctionParameterDecl( FunctionParameterDecl(
name='size', name='size',
type=ValueType(name='int'), type=ValueType(name='size_t'),
), ),
), ),
doc='Allocate array of mjtNums on mjData stack. Call mju_error on stack overflow.', # pylint: disable=line-too-long doc='Allocate array of mjtNums on mjData stack. Call mju_error on stack overflow.', # pylint: disable=line-too-long
@@ -794,7 +794,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
), ),
FunctionParameterDecl( FunctionParameterDecl(
name='size', name='size',
type=ValueType(name='int'), type=ValueType(name='size_t'),
), ),
), ),
doc='Allocate array of ints on mjData stack. Call mju_error on stack overflow.', # pylint: disable=line-too-long doc='Allocate array of ints on mjData stack. Call mju_error on stack overflow.', # pylint: disable=line-too-long
+52 -7
View File
@@ -1200,6 +1200,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
type=ValueType(name='int'), type=ValueType(name='int'),
doc='number of kinematic trees under world body', doc='number of kinematic trees under world body',
), ),
StructFieldDecl(
name='ngravcomp',
type=ValueType(name='int'),
doc='number of bodies with nonzero gravcomp',
),
StructFieldDecl( StructFieldDecl(
name='nemax', name='nemax',
type=ValueType(name='int'), type=ValueType(name='int'),
@@ -2095,6 +2100,13 @@ STRUCTS: Mapping[str, StructDecl] = dict([
), ),
doc='does light cast shadows (nlight x 1)', doc='does light cast shadows (nlight x 1)',
), ),
StructFieldDecl(
name='light_bulbradius',
type=PointerType(
inner_type=ValueType(name='float'),
),
doc='light radius for soft shadows (nlight x 1)',
),
StructFieldDecl( StructFieldDecl(
name='light_active', name='light_active',
type=PointerType( type=PointerType(
@@ -2116,13 +2128,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
), ),
doc='direction rel. to body frame (nlight x 3)', doc='direction rel. to body frame (nlight x 3)',
), ),
StructFieldDecl(
name='light_radius',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='radius of the light (nlight x 1)',
),
StructFieldDecl( StructFieldDecl(
name='light_poscom0', name='light_poscom0',
type=PointerType( type=PointerType(
@@ -2977,6 +2982,20 @@ STRUCTS: Mapping[str, StructDecl] = dict([
), ),
doc='reflectance (0: disable) (nmat x 1)', doc='reflectance (0: disable) (nmat x 1)',
), ),
StructFieldDecl(
name='mat_metallic',
type=PointerType(
inner_type=ValueType(name='float'),
),
doc='metallic coef (nmat x 1)',
),
StructFieldDecl(
name='mat_roughness',
type=PointerType(
inner_type=ValueType(name='float'),
),
doc='roughness coef (nmat x 1)',
),
StructFieldDecl( StructFieldDecl(
name='mat_rgba', name='mat_rgba',
type=PointerType( type=PointerType(
@@ -5624,6 +5643,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
type=ValueType(name='mjtByte'), type=ValueType(name='mjtByte'),
doc='does light cast shadows', doc='does light cast shadows',
), ),
StructFieldDecl(
name='bulbradius',
type=ValueType(name='float'),
doc='bulb radius for soft shadows',
),
), ),
)), )),
('mjvOption', ('mjvOption',
@@ -6719,6 +6743,13 @@ STRUCTS: Mapping[str, StructDecl] = dict([
), ),
doc='', doc='',
), ),
StructFieldDecl(
name='light_bulbradius',
type=PointerType(
inner_type=ValueType(name='float'),
),
doc='',
),
StructFieldDecl( StructFieldDecl(
name='light_active', name='light_active',
type=PointerType( type=PointerType(
@@ -7146,6 +7177,20 @@ STRUCTS: Mapping[str, StructDecl] = dict([
), ),
doc='', doc='',
), ),
StructFieldDecl(
name='mat_metallic',
type=PointerType(
inner_type=ValueType(name='float'),
),
doc='',
),
StructFieldDecl(
name='mat_roughness',
type=PointerType(
inner_type=ValueType(name='float'),
),
doc='',
),
StructFieldDecl( StructFieldDecl(
name='mat_rgba', name='mat_rgba',
type=PointerType( type=PointerType(
+12 -2
View File
@@ -56,7 +56,10 @@ from mujoco.mjx._src.collision_primitive import plane_ellipsoid
from mujoco.mjx._src.collision_primitive import plane_sphere from mujoco.mjx._src.collision_primitive import plane_sphere
from mujoco.mjx._src.collision_primitive import sphere_capsule from mujoco.mjx._src.collision_primitive import sphere_capsule
from mujoco.mjx._src.collision_primitive import sphere_sphere from mujoco.mjx._src.collision_primitive import sphere_sphere
from mujoco.mjx._src.collision_sdf import capsule_cylinder
from mujoco.mjx._src.collision_sdf import capsule_ellipsoid from mujoco.mjx._src.collision_sdf import capsule_ellipsoid
from mujoco.mjx._src.collision_sdf import cylinder_cylinder
from mujoco.mjx._src.collision_sdf import ellipsoid_cylinder
from mujoco.mjx._src.collision_sdf import ellipsoid_ellipsoid from mujoco.mjx._src.collision_sdf import ellipsoid_ellipsoid
from mujoco.mjx._src.collision_types import FunctionKey from mujoco.mjx._src.collision_types import FunctionKey
from mujoco.mjx._src.types import Contact from mujoco.mjx._src.types import Contact
@@ -82,8 +85,11 @@ _COLLISION_FUNC = {
(GeomType.CAPSULE, GeomType.CAPSULE): capsule_capsule, (GeomType.CAPSULE, GeomType.CAPSULE): capsule_capsule,
(GeomType.CAPSULE, GeomType.BOX): capsule_convex, (GeomType.CAPSULE, GeomType.BOX): capsule_convex,
(GeomType.CAPSULE, GeomType.ELLIPSOID): capsule_ellipsoid, (GeomType.CAPSULE, GeomType.ELLIPSOID): capsule_ellipsoid,
(GeomType.CAPSULE, GeomType.CYLINDER): capsule_cylinder,
(GeomType.CAPSULE, GeomType.MESH): capsule_convex, (GeomType.CAPSULE, GeomType.MESH): capsule_convex,
(GeomType.ELLIPSOID, GeomType.ELLIPSOID): ellipsoid_ellipsoid, (GeomType.ELLIPSOID, GeomType.ELLIPSOID): ellipsoid_ellipsoid,
(GeomType.ELLIPSOID, GeomType.CYLINDER): ellipsoid_cylinder,
(GeomType.CYLINDER, GeomType.CYLINDER): cylinder_cylinder,
(GeomType.BOX, GeomType.BOX): convex_convex, (GeomType.BOX, GeomType.BOX): convex_convex,
(GeomType.BOX, GeomType.MESH): convex_convex, (GeomType.BOX, GeomType.MESH): convex_convex,
(GeomType.MESH, GeomType.MESH): convex_convex, (GeomType.MESH, GeomType.MESH): convex_convex,
@@ -102,7 +108,7 @@ def has_collision_fn(t1: GeomType, t2: GeomType) -> bool:
def geom_pairs( def geom_pairs(
m: Union[Model, mujoco.MjModel], m: Union[Model, mujoco.MjModel],
) -> Iterator[Tuple[int, int, int]]: ) -> Iterator[Tuple[int, int, int]]:
"""Returns geom pairs to check for collisions. """Yields geom pairs to check for collisions.
Args: Args:
m: a MuJoCo or MJX model m: a MuJoCo or MJX model
@@ -345,7 +351,11 @@ def collision(m: Model, d: Data) -> Data:
for key, contact in groups.items(): for key, contact in groups.items():
# determine which contacts we'll use for collision testing by running a # determine which contacts we'll use for collision testing by running a
# broad phase cull if requested # broad phase cull if requested
if max_geom_pairs > -1 and contact.geom.shape[0] > max_geom_pairs: if (
max_geom_pairs > -1
and contact.geom.shape[0] > max_geom_pairs
and not set(key.types) & _GEOM_NO_BROADPHASE
):
pos1, pos2 = d.geom_xpos[contact.geom.T] pos1, pos2 = d.geom_xpos[contact.geom.T]
size1, size2 = m.geom_rbound[contact.geom.T] size1, size2 = m.geom_rbound[contact.geom.T]
dist = jax.vmap(jp.linalg.norm)(pos2 - pos1) - (size1 + size2) dist = jax.vmap(jp.linalg.norm)(pos2 - pos1) - (size1 + size2)
+25 -1
View File
@@ -264,6 +264,29 @@ class EllipsoidCollisionTest(parameterized.TestCase):
_assert_attr_eq( _assert_attr_eq(
dx.contact, d.contact, field.name, 'ellipsoid-capsule', 1e-4) dx.contact, d.contact, field.name, 'ellipsoid-capsule', 1e-4)
_ELLIPSOID_CYLINDER = """
<mujoco>
<worldbody>
<body>
<geom size=".15 .05" type="cylinder"/>
</body>
<body pos="0 0 0.09">
<freejoint/>
<geom size=".15 .03 .05" type="ellipsoid"/>
</body>
</worldbody>
</mujoco>
"""
def test_ellipsoid_cylinder(self):
"""Tests ellipsoid cylinder contact."""
d, dx = _collide(self._ELLIPSOID_CYLINDER)
d.contact.pos[0][2] = 0.04 # MJX finds the deepest point on the surface
self.assertLess(dx.contact.dist[0], 0)
for field in dataclasses.fields(Contact):
_assert_attr_eq(
dx.contact, d.contact, field.name, 'ellipsoid-cylinder', 1e-4)
class CapsuleCollisionTest(parameterized.TestCase): class CapsuleCollisionTest(parameterized.TestCase):
_CAP_PLANE = """ _CAP_PLANE = """
@@ -775,7 +798,8 @@ class DimTest(parameterized.TestCase):
def test_ncon(self): def test_ncon(self):
m = test_util.load_test_file('constraints.xml') m = test_util.load_test_file('constraints.xml')
dim = collision_driver.make_condim(m) dim = collision_driver.make_condim(m)
np.testing.assert_array_equal(dim, np.array([3] * 16)) expected = [1] * 4 + [3] * 20 + [4] * 4 + [6] * 4
np.testing.assert_array_equal(dim, np.array(expected))
def test_disable_contact(self): def test_disable_contact(self):
m = test_util.load_test_file('constraints.xml') m = test_util.load_test_file('constraints.xml')
+90 -9
View File
@@ -85,6 +85,43 @@ def _ellipsoid(pos: jax.Array, size: jax.Array) -> jax.Array:
return k0 * (k0 - 1.0) / (k1 + (k1 == 0.0) * 1e-12) return k0 * (k0 - 1.0) / (k1 + (k1 == 0.0) * 1e-12)
@jax.custom_jvp
def _cylinder(pos: jax.Array, size: jax.Array) -> jax.Array:
a0 = jp.sqrt(pos[0] * pos[0] + pos[1] * pos[1]) - size[0]
a1 = jp.abs(pos[2]) - size[1]
b0 = jp.maximum(a0, 0)
b1 = jp.maximum(a1, 0)
return jp.minimum(jp.maximum(a0, a1), 0) + jp.sqrt(b0 * b0 + b1 * b1)
def _cylinder_grad(x: jax.Array, size: jax.Array) -> jax.Array:
"""Gradient of the cylinder SDF wrt query point and singularities removed."""
c = jp.sqrt(x[0]*x[0]+x[1]*x[1])
e = jp.abs(x[2])
a = jp.array([c - size[0], e - size[1]])
b = jp.array([jp.maximum(a[0], 0), jp.maximum(a[1], 0)])
j = jp.argmax(a)
bnorm = jp.sqrt(b[0]*b[0] + b[1]*b[1])
bnorm += jp.allclose(bnorm, 0) * 1e-12
grada = jp.array([
x[0] / (c + jp.allclose(c, 0) * 1e-12),
x[1] / (c + jp.allclose(c, 0) * 1e-12),
x[2] / (e + jp.allclose(e, 0) * 1e-12),
])
gradm = jp.array([[grada[0], grada[1], 0], [0, 0, grada[2]]])
gradb = grada * b[jp.array([0, 0, 1])] / bnorm
return jp.where(a[j] < 0, gradm[j], gradb)
@_cylinder.defjvp
def cylinder_jvp(primals, tangents):
x, y = primals
x_dot, _ = tangents
primal_out = _cylinder(x, y)
tangent_out = jp.dot(_cylinder_grad(x, y), x_dot)
return primal_out, tangent_out
def _to_local(f: SDFFn, pos: jax.Array, mat: jax.Array)-> SDFFn: def _to_local(f: SDFFn, pos: jax.Array, mat: jax.Array)-> SDFFn:
return lambda p: f(mat.T @ (p - pos)) return lambda p: f(mat.T @ (p - pos))
@@ -134,29 +171,73 @@ def _gradient_descent(
def _optim( def _optim(
d1, d2, info1: GeomInfo, info2: GeomInfo d1, d2, info1: GeomInfo, info2: GeomInfo, x0: jax.Array,
) -> Tuple[jax.Array, jax.Array, jax.Array]: ) -> Collision:
"""Optimizes the clearance function.""" """Optimizes the clearance function."""
d1 = functools.partial(d1, size=info1.size) d1 = functools.partial(d1, size=info1.size)
d1 = _to_local(d1, info1.pos, info1.mat) d1 = _to_local(d1, info1.pos, info1.mat)
d2 = functools.partial(d2, size=info2.size) d2 = functools.partial(d2, size=info2.size)
d2 = _to_local(d2, info2.pos, info2.mat) d2 = _to_local(d2, info2.pos, info2.mat)
fn = _clearance(d1, d2) fn = _clearance(d1, d2)
_, pos = _gradient_descent(fn, 0.5 * (info1.pos + info2.pos), 10) _, pos = _gradient_descent(fn, x0, 10)
dist = d1(pos) + d2(pos) dist = d1(pos) + d2(pos)
n = jax.grad(d1)(pos) n = jax.grad(d1)(pos) - jax.grad(d2)(pos)
return pos, dist, n return dist, pos, math.make_frame(n)
@collider(ncon=1) @collider(ncon=1)
def capsule_ellipsoid(c: GeomInfo, e: GeomInfo) -> Collision: def capsule_ellipsoid(c: GeomInfo, e: GeomInfo) -> Collision:
""""Calculates contact between a capsule and an ellipsoid.""" """"Calculates contact between a capsule and an ellipsoid."""
pos, dist, n = _optim(_capsule, _ellipsoid, c, e) x0 = 0.5 * (c.pos + e.pos)
return dist, pos, math.make_frame(n) return _optim(_capsule, _ellipsoid, c, e, x0)
@collider(ncon=2)
def capsule_cylinder(ca: GeomInfo, cy: GeomInfo) -> Collision:
""""Calculates contact between a capsule and a cylinder."""
# TODO: improve robustness
# Near sharp corners, the SDF might give the penetration depth with respect
# to a surface that is not in collision. Possible solutions is to find the
# contact points analytically or to change the SDF depending on the relative
# pose of the bodies.
mid = 0.5 * (ca.pos + cy.pos)
vec = ca.mat[:, 2] * ca.size[1]
x0 = jp.array([mid - vec, mid + vec])
optim_ = functools.partial(_optim, _capsule, _cylinder, ca, cy)
return jax.vmap(optim_)(x0)
@collider(ncon=1) @collider(ncon=1)
def ellipsoid_ellipsoid(e1: GeomInfo, e2: GeomInfo) -> Collision: def ellipsoid_ellipsoid(e1: GeomInfo, e2: GeomInfo) -> Collision:
""""Calculates contact between two ellipsoids.""" """"Calculates contact between two ellipsoids."""
pos, dist, n = _optim(_ellipsoid, _ellipsoid, e1, e2) x0 = 0.5 * (e1.pos + e2.pos)
return dist, pos, math.make_frame(n) return _optim(_ellipsoid, _ellipsoid, e1, e2, x0)
@collider(ncon=1)
def ellipsoid_cylinder(e: GeomInfo, c: GeomInfo) -> Collision:
""""Calculates contact between and ellipsoid and a cylinder."""
x0 = 0.5 * (e.pos + c.pos)
return _optim(_ellipsoid, _cylinder, e, c, x0)
@collider(ncon=4)
def cylinder_cylinder(c1: GeomInfo, c2: GeomInfo) -> Collision:
""""Calculates contact between a cylinder and a cylinder."""
# TODO: improve robustness
# Near sharp corners, the SDF might give the penetration depth with respect
# to a surface that is not in collision. Possible solutions is to find the
# contact points analytically or to change the SDF depending on the relative
# pose of the bodies.
basis = math.make_frame(c2.pos - c1.pos)
mid = 0.5 * (c1.pos + c2.pos)
r = jp.maximum(c1.size[0], c2.size[0])
x0 = jp.array([
mid + r * basis[1],
mid + r * basis[2],
mid - r * basis[1],
mid - r * basis[2],
])
optim_ = functools.partial(_optim, _cylinder, _cylinder, c1, c2)
return jax.vmap(optim_)(x0)
+46 -25
View File
@@ -284,35 +284,54 @@ def _instantiate_contact(m: Model, d: Data) -> Optional[_Efc]:
if d.ncon == 0: if d.ncon == 0:
return None return None
@jax.vmap def contact_efc(c: Contact, condim: int):
def fn(c: Contact):
dist = c.dist - c.includemargin
geom_bodyid = jp.array(m.geom_bodyid)
body1, body2 = geom_bodyid[c.geom1], geom_bodyid[c.geom2]
diff = support.jac_dif_pair(m, d, c.pos, body1, body2)
t = m.body_invweight0[body1, 0] + m.body_invweight0[body2, 0]
# rotate Jacobian differences to contact frame @jax.vmap
diff_con = c.frame @ diff.T def fn(c: Contact):
dist = c.dist - c.includemargin
active = dist < 0
body1, body2 = jp.array(m.geom_bodyid)[c.geom]
jac1p, jac1r = support.jac(m, d, c.pos, body1)
jac2p, jac2r = support.jac(m, d, c.pos, body2)
diff = c.frame @ (jac2p - jac1p).T
if condim > 3: # only calculate rotational diff if needed
diff = jp.concatenate((diff, c.frame @ (jac2r - jac1r).T), axis=0)
tran = m.body_invweight0[body1, 0] + m.body_invweight0[body2, 0]
# TODO(robotics-simulation): add support for other friction dimensions if condim == 1:
# 4 pyramidal friction directions return diff[0] * active, tran, dist * active, c.solref, c.solimp
js, invweights = [], []
for diff_tan, friction in zip(diff_con[1:], c.friction[:2]):
for f in (friction, -friction):
js.append(diff_con[0] + diff_tan * f)
invweights.append((t + f * f * t) * 2 * f * f / m.opt.impratio)
active = dist < 0 # a pair of opposing pyramid edges per friction dimension
j, invweight = jp.stack(js) * active, jp.stack(invweights) # repeat friction directions with positive and negative sign
pos = jp.repeat(dist, 4) * active fri = jp.repeat(c.friction[: condim - 1], 2, axis=0).at[1::2].mul(-1)
solref, solimp = jp.tile(c.solref, (4, 1)), jp.tile(c.solimp, (4, 1)) # repeat condims of jacdiff to match +/- friction directions
j = diff[0] + jp.repeat(diff[1:condim], 2, axis=0) * fri[:, None]
# pyramidal has common invweight across all edges
diag_approx = tran + fri[0] * fri[0] * tran
inv_w = diag_approx * 2 * fri[0] * fri[0] / m.opt.impratio
repeat_fn = lambda x: jp.repeat(x[None], (condim - 1) * 2, axis=0)
inv_w, pos, solref, solimp = jax.tree_util.tree_map(
repeat_fn, (inv_w, dist, c.solref, c.solimp)
)
return j * active, inv_w, pos * active, solref, solimp
return j, invweight, pos, solref, solimp return fn(c)
res = fn(d.contact) # group efc calculations by condim
# remove contact grouping dimension: dims, begs = np.unique(d.contact.dim, return_index=True)
j, invweight, pos, solref, solimp = jax.tree_util.tree_map(jp.concatenate, res) efcs = []
for i in range(len(dims)):
dim, beg = dims[i], begs[i]
end = begs[i + 1] if i < len(dims) - 1 else None
c = jax.tree_util.tree_map(lambda x, b=beg, e=end: x[b:e], d.contact)
efc = contact_efc(c, dim)
if dim > 1:
# remove efc grouping dimension
efc = jax.tree_util.tree_map(jp.concatenate, efc)
efcs.append(efc)
efc = jax.tree_util.tree_map(lambda *x: jp.concatenate(x), *efcs)
j, invweight, pos, solref, solimp = efc
frictionloss = jp.zeros_like(pos) frictionloss = jp.zeros_like(pos)
return _Efc(j, pos, pos, invweight, solref, solimp, frictionloss) return _Efc(j, pos, pos, invweight, solref, solimp, frictionloss)
@@ -323,7 +342,9 @@ def counts(efc_type: np.ndarray) -> Tuple[int, int, int, int]:
ne = (efc_type == ConstraintType.EQUALITY).sum() ne = (efc_type == ConstraintType.EQUALITY).sum()
nf = 0 # no support for friction loss yet nf = 0 # no support for friction loss yet
nl = (efc_type == ConstraintType.LIMIT_JOINT).sum() nl = (efc_type == ConstraintType.LIMIT_JOINT).sum()
nc = (efc_type == ConstraintType.CONTACT_PYRAMIDAL).sum() nc_f = (efc_type == ConstraintType.CONTACT_FRICTIONLESS).sum()
nc_p = (efc_type == ConstraintType.CONTACT_PYRAMIDAL).sum()
nc = nc_f + nc_p
return ne, nf, nl, nc return ne, nf, nl, nc
+26 -8
View File
@@ -48,13 +48,31 @@ class ConstraintTest(absltest.TestCase):
mujoco.mj_forward(m, d) mujoco.mj_forward(m, d)
mx = mjx.put_model(m) mx = mjx.put_model(m)
dx = mjx.put_data(m, d) dx = mjx.put_data(m, d)
dx = mjx.make_constraint(mx, dx) dx = mjx.make_constraint(mx, dx)
nnz = dx.efc_J.any(axis=1) d_efc_j = d.efc_J.reshape((-1, m.nv))
_assert_eq(d.efc_J, dx.efc_J[nnz].reshape(-1), 'efc_J')
_assert_eq(d.efc_D, dx.efc_D[nnz], 'efc_D') # ne, nf, nl order matches
_assert_eq(d.efc_aref, dx.efc_aref[nnz], 'efc_aref') efl = d.ne + d.nf + d.nl
_assert_eq(d.efc_frictionloss, dx.efc_frictionloss[nnz], 'efc_frictionloss') _assert_eq(d_efc_j[:efl], dx.efc_J[:efl], 'efc_J')
_assert_eq(d.efc_D[:efl], dx.efc_D[:efl], 'efc_D')
_assert_eq(d.efc_aref[:efl], dx.efc_aref[:efl], 'efc_aref')
_assert_eq(dx.efc_frictionloss, 0, 'efc_frictionloss')
# contact order might not match, so check efcs contact by contact
for i in range(d.ncon):
geom_match = (dx.contact.geom == d.contact.geom[i]).all(axis=-1)
geom_match &= (dx.contact.pos == d.contact.pos[i]).all(axis=-1)
self.assertTrue(geom_match.any(), f'contact {i} not found in MJX contact')
j = np.nonzero(geom_match)[0][0]
self.assertEqual(d.contact.dim[i], dx.contact.dim[j])
nc = max(1, (d.contact.dim[i] - 1) * 2)
d_beg, dx_beg = d.contact.efc_address[i], dx.contact.efc_address[j]
d_end, dx_end = d_beg + nc, dx_beg + nc
_assert_eq(d_efc_j[d_beg:d_end], dx.efc_J[dx_beg:dx_end], 'efc_J')
_assert_eq(d.efc_D[d_beg:d_end], dx.efc_D[dx_beg:dx_end], 'efc_D')
d_efc_aref = d.efc_aref[d_beg:d_end]
dx_efc_aref = dx.efc_aref[dx_beg:dx_end]
_assert_eq(d_efc_aref, dx_efc_aref, 'efc_aref')
def test_disable_refsafe(self): def test_disable_refsafe(self):
m = test_util.load_test_file('constraints.xml') m = test_util.load_test_file('constraints.xml')
@@ -87,9 +105,9 @@ class ConstraintTest(absltest.TestCase):
self.assertEqual(ne, 0) self.assertEqual(ne, 0)
self.assertEqual(nf, 0) self.assertEqual(nf, 0)
self.assertEqual(nl, 2) self.assertEqual(nl, 2)
self.assertEqual(nc, 64) self.assertEqual(nc, 148)
dx = constraint.make_constraint(mjx.put_model(m), mjx.make_data(m)) dx = constraint.make_constraint(mjx.put_model(m), mjx.make_data(m))
self.assertEqual(dx.efc_J.shape[0], 66) # only joint range, contact self.assertEqual(dx.efc_J.shape[0], 150) # only joint range, contact
def test_disable_contact(self): def test_disable_contact(self):
m = test_util.load_test_file('constraints.xml') m = test_util.load_test_file('constraints.xml')
+2 -2
View File
@@ -18,7 +18,7 @@ import copy
import dataclasses import dataclasses
import typing import typing
from typing import Any, Dict, Optional, Sequence, TypeVar, Union from typing import Dict, Optional, Sequence, Tuple, TypeVar, Union
import jax import jax
import numpy as np import numpy as np
@@ -122,7 +122,7 @@ class PyTreeNode:
raise NotImplementedError raise NotImplementedError
@classmethod @classmethod
def fields(cls) -> tuple[dataclasses.Field[Any], ...]: def fields(cls) -> Tuple[dataclasses.Field, ...]: # pylint: disable=g-bare-generic
return dataclasses.fields(cls) return dataclasses.fields(cls)
def tree_replace( def tree_replace(
+22 -13
View File
@@ -68,9 +68,6 @@ def put_model(m: mujoco.MjModel, device=None) -> types.Model:
if m.ntendon: if m.ntendon:
raise NotImplementedError('tendons are not supported') raise NotImplementedError('tendons are not supported')
if (m.geom_condim != 3).any() or (m.pair_dim != 3).any():
raise NotImplementedError('only condim=3 is supported')
if m.body_gravcomp.any(): if m.body_gravcomp.any():
raise NotImplementedError('gravcomp is not supported') raise NotImplementedError('gravcomp is not supported')
@@ -321,13 +318,27 @@ def _make_contact(
"""Converts mujoco.structs._MjContactList into mjx.Contact.""" """Converts mujoco.structs._MjContactList into mjx.Contact."""
fields = {f.name: getattr(c, f.name) for f in types.Contact.fields()} fields = {f.name: getattr(c, f.name) for f in types.Contact.fields()}
fields['frame'] = fields['frame'].reshape((-1, 3, 3)) fields['frame'] = fields['frame'].reshape((-1, 3, 3))
pad_size = dim.size - c.dist.shape[0] # reorder contacts so that their condims match those specified in dim.
pad_fn = lambda x: np.concatenate( # if we have fewer Contacts for a condim range, pad the range with zeros
(x, np.zeros((pad_size,) + x.shape[1:], dtype=x.dtype))
) # build a map for where to find a dim-matching contact, or -1 if none
fields = jax.tree_util.tree_map(pad_fn, fields) contact_map = np.zeros_like(dim) - 1
fields['dist'][-pad_size:] = np.inf for i, di in enumerate(fields['dim']):
# TODO(erikfrey): move contacts to appropriate dim index space = [j for j, dj in enumerate(dim) if di == dj and contact_map[j] == -1]
if not space:
# this can happen if max_geom_pairs or max_contact_points is too low
raise ValueError(f'unable to place Contact[{i}], no space in condim {di}')
contact_map[space[0]] = i
if contact_map.size > 0:
# reorganize contact according, with a zero contact at the end for -1
zero = jax.tree_util.tree_map(
lambda x: np.zeros((1,) + x.shape[1:], dtype=x.dtype), fields
)
zero['dist'][:] = np.finfo(float).max
fields = jax.tree_util.tree_map(lambda *x: np.concatenate(x), fields, zero)
fields = jax.tree_util.tree_map(lambda x: x[contact_map], fields)
fields['dim'] = dim fields['dim'] = dim
fields['efc_address'] = efc_address fields['efc_address'] = efc_address
@@ -398,9 +409,7 @@ def put_data(m: mujoco.MjModel, d: mujoco.MjData, device=None) -> types.Data:
fields['qLDiagInv'] = np.zeros(0) fields['qLDiagInv'] = np.zeros(0)
fields['contact'] = _make_contact(d.contact, dim, efc_address) fields['contact'] = _make_contact(d.contact, dim, efc_address)
fields.update( fields.update(ne=ne, nf=nf, nl=nl, nefc=nefc, ncon=ncon, efc_type=efc_type)
dict(ne=ne, nf=nf, nl=nl, nefc=nefc, ncon=ncon, efc_type=efc_type)
)
# copy because device_put is async: # copy because device_put is async:
data = types.Data(**{k: copy.copy(v) for k, v in fields.items()}) data = types.Data(**{k: copy.copy(v) for k, v in fields.items()})
+10 -25
View File
@@ -63,7 +63,7 @@ _MULTIPLE_CONVEX_OBJECTS = """
_MULTIPLE_CONSTRAINTS = """ _MULTIPLE_CONSTRAINTS = """
<mujoco> <mujoco>
<worldbody> <worldbody>
<geom type="plane" size="3 3 .01"/> <geom type="plane" size="3 3 .01" condim="6"/>
<body name="cap1" pos="-.3 -.3 .2"> <body name="cap1" pos="-.3 -.3 .2">
<freejoint/> <freejoint/>
<geom type="capsule" size=".2 .05"/> <geom type="capsule" size=".2 .05"/>
@@ -173,22 +173,6 @@ class ModelIOTest(parameterized.TestCase):
</tendon> </tendon>
</mujoco>""")) </mujoco>"""))
def test_condim_not_implemented(self):
with self.assertRaises(NotImplementedError):
mjx.put_model(mujoco.MjModel.from_xml_string("""
<mujoco>
<worldbody>
<body>
<freejoint/>
<geom size="0.05" condim="1"/>
</body>
<body>
<freejoint/>
<geom size="0.05" condim="1"/>
</body>
</worldbody>
</mujoco>"""))
def test_gravcomp_not_implemented(self): def test_gravcomp_not_implemented(self):
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
mjx.put_model(mujoco.MjModel.from_xml_string(""" mjx.put_model(mujoco.MjModel.from_xml_string("""
@@ -345,21 +329,21 @@ class DataIOTest(parameterized.TestCase):
np.testing.assert_allclose(dx.site_xmat.reshape((1, 9)), d.site_xmat) np.testing.assert_allclose(dx.site_xmat.reshape((1, 9)), d.site_xmat)
# efc_ are also shape transformed and padded # efc_ are also shape transformed and padded
self.assertEqual(dx.efc_J.shape, (21, 8)) # nefc, nv self.assertEqual(dx.efc_J.shape, (45, 8)) # nefc, nv
d_efc_j = d.efc_J.reshape((-1, 8)) d_efc_j = d.efc_J.reshape((-1, 8))
np.testing.assert_allclose(dx.efc_J[:3], d_efc_j[:3]) # connect eq np.testing.assert_allclose(dx.efc_J[:3], d_efc_j[:3]) # connect eq
np.testing.assert_allclose(dx.efc_J[3], d_efc_j[3]) # one active limit np.testing.assert_allclose(dx.efc_J[3], d_efc_j[3]) # one active limit
np.testing.assert_allclose(dx.efc_J[4], 0) # one inactive limit np.testing.assert_allclose(dx.efc_J[4], 0) # one inactive limit
np.testing.assert_allclose(dx.efc_J[5:9], d_efc_j[4:8]) # contact np.testing.assert_allclose(dx.efc_J[5:15], d_efc_j[4:14]) # contact
np.testing.assert_allclose(dx.efc_J[9:], 0) # no contact np.testing.assert_allclose(dx.efc_J[15:], 0) # no contact
# check another efc_ too # check another efc_ too
self.assertEqual(dx.efc_aref.shape, (21,)) # nefc self.assertEqual(dx.efc_aref.shape, (45,)) # nefc
np.testing.assert_allclose(dx.efc_aref[:3], d.efc_aref[:3]) np.testing.assert_allclose(dx.efc_aref[:3], d.efc_aref[:3])
np.testing.assert_allclose(dx.efc_aref[3], d.efc_aref[3]) np.testing.assert_allclose(dx.efc_aref[3], d.efc_aref[3])
np.testing.assert_allclose(dx.efc_aref[4], 0) np.testing.assert_allclose(dx.efc_aref[4], 0)
np.testing.assert_allclose(dx.efc_aref[5:9], d.efc_aref[4:8]) np.testing.assert_allclose(dx.efc_aref[5:15], d.efc_aref[4:14])
np.testing.assert_allclose(dx.efc_aref[9:], 0) np.testing.assert_allclose(dx.efc_aref[15:], 0)
# check sparse transform is correct # check sparse transform is correct
m.opt.jacobian = mujoco.mjtJacobian.mjJAC_SPARSE m.opt.jacobian = mujoco.mjtJacobian.mjJAC_SPARSE
@@ -416,9 +400,10 @@ class DataIOTest(parameterized.TestCase):
np.testing.assert_allclose(d_2.site_xmat, d.site_xmat) np.testing.assert_allclose(d_2.site_xmat, d.site_xmat)
# efc_* are also shape transformed and filtered # efc_* are also shape transformed and filtered
self.assertEqual(d_2.efc_J.shape, (64,)) # nefc * nv self.assertEqual(d_2.nefc, 14)
self.assertEqual(d_2.efc_J.shape, (112,)) # nefc * nv
np.testing.assert_allclose(d_2.efc_J, d.efc_J) np.testing.assert_allclose(d_2.efc_J, d.efc_J)
self.assertEqual(d_2.efc_aref.shape, (8,)) # nefc self.assertEqual(d_2.efc_aref.shape, (14,)) # nefc
np.testing.assert_allclose(d_2.efc_aref, d.efc_aref) np.testing.assert_allclose(d_2.efc_aref, d.efc_aref)
np.testing.assert_allclose(d_2.contact.efc_address, d.contact.efc_address) np.testing.assert_allclose(d_2.contact.efc_address, d.contact.efc_address)
-13
View File
@@ -149,19 +149,6 @@ def jac(
return jacp, jacr return jacp, jacr
def jac_dif_pair(
m: Model,
d: Data,
pos: jax.Array,
body_1: jax.Array,
body_2: jax.Array,
) -> jax.Array:
"""Compute Jacobian difference for two body points."""
jacp2, _ = jac(m, d, pos, body_2)
jacp1, _ = jac(m, d, pos, body_1)
return jacp2 - jacp1
def apply_ft( def apply_ft(
m: Model, m: Model,
d: Data, d: Data,
+4 -4
View File
@@ -17,7 +17,7 @@
import os import os
import sys import sys
import time import time
from typing import Dict, Tuple from typing import Dict, Optional, Tuple
from xml.etree import ElementTree as ET from xml.etree import ElementTree as ET
from etils import epath from etils import epath
@@ -201,9 +201,9 @@ def _make_geom(
def _make_actuator( def _make_actuator(
actuator_type: str, actuator_type: str,
joint: str | None = None, joint: Optional[str] = None,
site: str | None = None, site: Optional[str] = None,
refsite: str | None = None, refsite: Optional[str] = None,
) -> Dict[str, str]: ) -> Dict[str, str]:
"""Returns attributes for an actuator.""" """Returns attributes for an actuator."""
if joint: if joint:
+3 -1
View File
@@ -217,12 +217,14 @@ class ConstraintType(enum.IntEnum):
Attributes: Attributes:
EQUALITY: equality constraint EQUALITY: equality constraint
LIMIT_JOINT: joint limit LIMIT_JOINT: joint limit
CONTACT_FRICTIONLESS: frictionless contact
CONTACT_PYRAMIDAL: frictional contact, pyramidal friction cone CONTACT_PYRAMIDAL: frictional contact, pyramidal friction cone
""" """
EQUALITY = mujoco.mjtConstraint.mjCNSTR_EQUALITY EQUALITY = mujoco.mjtConstraint.mjCNSTR_EQUALITY
# unsupported: FRICTION_DOF, FRICTION_TENDON # unsupported: FRICTION_DOF, FRICTION_TENDON
LIMIT_JOINT = mujoco.mjtConstraint.mjCNSTR_LIMIT_JOINT LIMIT_JOINT = mujoco.mjtConstraint.mjCNSTR_LIMIT_JOINT
# unsupported: LIMIT_TENDON, CONTACT_FRICTIONLESS # unsupported: LIMIT_TENDON
CONTACT_FRICTIONLESS = mujoco.mjtConstraint.mjCNSTR_CONTACT_FRICTIONLESS
CONTACT_PYRAMIDAL = mujoco.mjtConstraint.mjCNSTR_CONTACT_PYRAMIDAL CONTACT_PYRAMIDAL = mujoco.mjtConstraint.mjCNSTR_CONTACT_PYRAMIDAL
# unsupported: CONTACT_ELLIPTIC # unsupported: CONTACT_ELLIPTIC
+21 -1
View File
@@ -14,7 +14,7 @@
</default> </default>
<worldbody> <worldbody>
<geom pos="0 0 -1" type="plane" size="10 10 .01"/> <geom pos="0 0 -1" type="plane" size="20 20 .01" condim="1"/>
<body name="anchor1" pos="-3 0 0"/> <body name="anchor1" pos="-3 0 0"/>
<body name="beam1" pos="-3 0 0"> <body name="beam1" pos="-3 0 0">
@@ -37,6 +37,26 @@
<joint name="joint4" axis="1 0 0" type="hinge" damping="1.0"/> <!-- tests no joint range --> <joint name="joint4" axis="1 0 0" type="hinge" damping="1.0"/> <!-- tests no joint range -->
<geom class="box"/> <geom class="box"/>
</body> </body>
<body name="box_condim1" pos="4 0 0">
<freejoint/>
<geom class="box" condim="1"/>
</body>
<body name="box_condim3" pos="5 0 0">
<freejoint/>
<geom class="box" condim="3"/>
</body>
<body name="box_condim4" pos="6 0 0">
<freejoint/>
<geom class="box" condim="4"/>
</body>
<body name="box_condim6" pos="6 0 0">
<freejoint/>
<geom class="box" condim="6"/>
</body>
</worldbody> </worldbody>
<equality> <equality>
+1
View File
@@ -2226,6 +2226,7 @@ This is useful for example when the MJB is not available as a file on disk.)"));
X(headlight); X(headlight);
X(directional); X(directional);
X(castshadow); X(castshadow);
X(bulbradius);
#undef X #undef X
#define X(var) DefinePyArray(mjvLight, #var, &MjvLightWrapper::var) #define X(var) DefinePyArray(mjvLight, #var, &MjvLightWrapper::var)
+18 -21
View File
@@ -256,6 +256,21 @@ static void clampVec(mjtNum* vec, const mjtNum* range, const mjtByte* limited, i
// return number of dofs given joint type
static int jnt_dofnum(mjtJoint type) {
if (type == mjJNT_FREE) {
return 6;
}
if (type == mjJNT_BALL) {
return 3;
}
return 1;
}
// (qpos, qvel, ctrl, act) => (qfrc_actuator, actuator_force, act_dot) // (qpos, qvel, ctrl, act) => (qfrc_actuator, actuator_force, act_dot)
void mj_fwdActuation(const mjModel* m, mjData* d) { void mj_fwdActuation(const mjModel* m, mjData* d) {
TM_START; TM_START;
@@ -469,7 +484,7 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
mju_mulMatTVec(d->qfrc_actuator, moment, force, nu, nv); mju_mulMatTVec(d->qfrc_actuator, moment, force, nu, nv);
// actuator-level gravity compensation // actuator-level gravity compensation
if (!mjDISABLED(mjDSBL_GRAVITY) && mju_norm3(m->opt.gravity)) { if (m->ngravcomp && !mjDISABLED(mjDSBL_GRAVITY) && mju_norm3(m->opt.gravity)) {
int njnt = m->njnt; int njnt = m->njnt;
for (int i=0; i < njnt; i++) { for (int i=0; i < njnt; i++) {
// skip if gravcomp added as passive force // skip if gravcomp added as passive force
@@ -477,28 +492,10 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
continue; continue;
} }
// get number of dofs for this joint
int dofnum;
switch (m->jnt_type[i]) {
case mjJNT_HINGE:
case mjJNT_SLIDE:
dofnum = 1;
break;
case mjJNT_BALL:
dofnum = 3;
break;
case mjJNT_FREE:
dofnum = 6;
break;
}
// add gravcomp force // add gravcomp force
int dofnum = jnt_dofnum(m->jnt_type[i]);
int dofadr = m->jnt_dofadr[i]; int dofadr = m->jnt_dofadr[i];
for (int j=0; j < dofnum; j++) { mju_addTo(d->qfrc_actuator + dofadr, d->qfrc_gravcomp + dofadr, dofnum);
d->qfrc_actuator[dofadr+j] += d->qfrc_gravcomp[dofadr+j];
}
} }
} }
+8 -2
View File
@@ -1524,14 +1524,20 @@ void* mj_stackAllocByte(mjData* d, size_t bytes, size_t alignment) {
// allocate mjtNums on the stack // allocate mjtNums on the stack
mjtNum* mj_stackAllocNum(mjData* d, int size) { mjtNum* mj_stackAllocNum(mjData* d, size_t size) {
if (mjUNLIKELY(size >= SIZE_MAX / sizeof(mjtNum))) {
mjERROR("requested size is too large.");
}
return (mjtNum*) stackalloc(d, size * sizeof(mjtNum), _Alignof(mjtNum)); return (mjtNum*) stackalloc(d, size * sizeof(mjtNum), _Alignof(mjtNum));
} }
// allocate ints on the stack // allocate ints on the stack
int* mj_stackAllocInt(mjData* d, int size) { int* mj_stackAllocInt(mjData* d, size_t size) {
if (mjUNLIKELY(size >= SIZE_MAX / sizeof(int))) {
mjERROR("requested size is too large.");
}
return (int*) stackalloc(d, size * sizeof(int), _Alignof(int)); return (int*) stackalloc(d, size * sizeof(int), _Alignof(int));
} }
+2 -2
View File
@@ -129,10 +129,10 @@ void mj__freeStack(mjData* d) __attribute__((noinline));
MJAPI void* mj_stackAllocByte(mjData* d, size_t bytes, size_t alignment); MJAPI void* mj_stackAllocByte(mjData* d, size_t bytes, size_t alignment);
// mjData stack allocate for array of mjtNums // mjData stack allocate for array of mjtNums
MJAPI mjtNum* mj_stackAllocNum(mjData* d, int size); MJAPI mjtNum* mj_stackAllocNum(mjData* d, size_t size);
// mjData stack allocate for array of ints // mjData stack allocate for array of ints
MJAPI int* mj_stackAllocInt(mjData* d, int size); MJAPI int* mj_stackAllocInt(mjData* d, size_t size);
// de-allocate data // de-allocate data
MJAPI void mj_deleteData(mjData* d); MJAPI void mj_deleteData(mjData* d);
+1 -1
View File
@@ -175,7 +175,7 @@ static void mj_springdamper(const mjModel* m, mjData* d) {
// body-level gravity compensation, return 1 if any, 0 otherwise // body-level gravity compensation, return 1 if any, 0 otherwise
static int mj_gravcomp(const mjModel* m, mjData* d) { static int mj_gravcomp(const mjModel* m, mjData* d) {
if (mjDISABLED(mjDSBL_GRAVITY) || mju_norm3(m->opt.gravity) == 0) { if (!m->ngravcomp || mjDISABLED(mjDSBL_GRAVITY) || mju_norm3(m->opt.gravity) == 0) {
return 0; return 0;
} }
+1
View File
@@ -2091,6 +2091,7 @@ void mjv_makeLights(const mjModel* m, mjData* d, mjvScene* scn) {
memset(thislight, 0, sizeof(mjvLight)); memset(thislight, 0, sizeof(mjvLight));
thislight->directional = m->light_directional[i]; thislight->directional = m->light_directional[i];
thislight->castshadow = m->light_castshadow[i]; thislight->castshadow = m->light_castshadow[i];
thislight->bulbradius = m->light_bulbradius[i];
if (!thislight->directional) { if (!thislight->directional) {
f2f(thislight->attenuation, m->light_attenuation+3*i, 3); f2f(thislight->attenuation, m->light_attenuation+3*i, 3);
thislight->exponent = m->light_exponent[i]; thislight->exponent = m->light_exponent[i];
+18
View File
@@ -110,6 +110,16 @@ const char* mjs_getError(mjSpec* s) {
// Detach body from mjSpec, return 0 if success.
int mjs_detachBody(mjSpec* s, const mjsBody* b) {
mjCModel* model = static_cast<mjCModel*>(s->element);
mjCBody* body = static_cast<mjCBody*>(b->element);
*model -= *body;
return 0;
}
// check if model has warnings // check if model has warnings
int mjs_isWarning(mjSpec* s) { int mjs_isWarning(mjSpec* s) {
mjCModel* modelC = static_cast<mjCModel*>(s->element); mjCModel* modelC = static_cast<mjCModel*>(s->element);
@@ -126,6 +136,14 @@ void mjs_deleteSpec(mjSpec* s) {
// delete body
void mjs_deleteBody(mjsBody* b) {
mjCBody* body = static_cast<mjCBody*>(b->element);
delete body;
}
// add child body to body, return child spec // add child body to body, return child spec
mjsBody* mjs_addBody(mjsBody* bodyspec, mjsDefault* defspec) { mjsBody* mjs_addBody(mjsBody* bodyspec, mjsDefault* defspec) {
mjCDef* def = defspec ? static_cast<mjCDef*>(defspec->element) : 0; mjCDef* def = defspec ? static_cast<mjCDef*>(defspec->element) : 0;
+11 -3
View File
@@ -347,7 +347,6 @@ typedef struct _mjsLight { // light specification
// frame // frame
double pos[3]; // position double pos[3]; // position
double dir[3]; // direction double dir[3]; // direction
double radius; // radius
mjtCamLight mode; // tracking mode mjtCamLight mode; // tracking mode
mjString targetbody; // target body for targeting mjString targetbody; // target body for targeting
@@ -355,6 +354,7 @@ typedef struct _mjsLight { // light specification
mjtByte active; // is light active mjtByte active; // is light active
mjtByte directional; // is light directional or spot mjtByte directional; // is light directional or spot
mjtByte castshadow; // does light cast shadows mjtByte castshadow; // does light cast shadows
double bulbradius; // bulb radius, for soft shadows
float attenuation[3]; // OpenGL attenuation (quadratic model) float attenuation[3]; // OpenGL attenuation (quadratic model)
float cutoff; // OpenGL cutoff float cutoff; // OpenGL cutoff
float exponent; // OpenGL exponent float exponent; // OpenGL exponent
@@ -515,6 +515,8 @@ typedef struct _mjsMaterial { // material specification
float specular; // specular float specular; // specular
float shininess; // shininess float shininess; // shininess
float reflectance; // reflectance float reflectance; // reflectance
float metallic; // metallic
float roughness; // roughness
float rgba[4]; // rgba float rgba[4]; // rgba
mjString info; // message appended to compiler errors mjString info; // message appended to compiler errors
} mjsMaterial; } mjsMaterial;
@@ -715,8 +717,8 @@ typedef struct _mjsKey { // keyframe specification
typedef struct _mjsDefault { // default specification typedef struct _mjsDefault { // default specification
mjString name; // name
mjElement* element; // element type mjElement* element; // element type
mjString name; // class name
mjsJoint* joint; // joint defaults mjsJoint* joint; // joint defaults
mjsGeom* geom; // geom defaults mjsGeom* geom; // geom defaults
mjsSite* site; // site defaults mjsSite* site; // site defaults
@@ -762,10 +764,13 @@ MJAPI void mjs_deleteSpec(mjSpec* s);
MJAPI int mjs_attachBody(mjsFrame* parent, const mjsBody* child, MJAPI int mjs_attachBody(mjsFrame* parent, const mjsBody* child,
const char* prefix, const char* suffix); const char* prefix, const char* suffix);
// Attach child frame to a parent body, return 0 if success. // Attach child frame to a parent body, return 0 on success.
MJAPI int mjs_attachFrame(mjsBody* parent, const mjsFrame* child, MJAPI int mjs_attachFrame(mjsBody* parent, const mjsFrame* child,
const char* prefix, const char* suffix); const char* prefix, const char* suffix);
// Detach body from mjSpec, remove all references, return 0 on success.
MJAPI int mjs_detachBody(mjSpec* s, const mjsBody* b);
//---------------------------------- Add tree elements --------------------------------------------- //---------------------------------- Add tree elements ---------------------------------------------
@@ -793,6 +798,9 @@ MJAPI mjsLight* mjs_addLight(mjsBody* body, mjsDefault* def);
// Add frame to body. // Add frame to body.
MJAPI mjsFrame* mjs_addFrame(mjsBody* body, mjsFrame* parentframe); MJAPI mjsFrame* mjs_addFrame(mjsBody* body, mjsFrame* parentframe);
// Delete body. TODO: make this a general mjs_deleteElement function
MJAPI void mjs_deleteBody(mjsBody* b);
//---------------------------------- Add non-tree elements ----------------------------------------- //---------------------------------- Add non-tree elements -----------------------------------------
+3
View File
@@ -218,6 +218,7 @@ void mjs_defaultLight(mjsLight& light) {
// intrinsics // intrinsics
light.castshadow = 1; light.castshadow = 1;
light.bulbradius = 0.02;
light.active = 1; light.active = 1;
light.dir[2] = -1; light.dir[2] = -1;
light.attenuation[0] = 1; light.attenuation[0] = 1;
@@ -305,6 +306,8 @@ void mjs_defaultMaterial(mjsMaterial& material) {
material.specular = 0.5; material.specular = 0.5;
material.shininess = 0.5; material.shininess = 0.5;
material.reflectance = 0; material.reflectance = 0;
material.metallic = 1.0;
material.roughness = 1.0;
material.rgba[0] = material.rgba[1] = material.rgba[2] = material.rgba[3] = 1; material.rgba[0] = material.rgba[1] = material.rgba[2] = material.rgba[3] = 1;
} }
+102 -8
View File
@@ -216,6 +216,16 @@ void mjCModel::CopyList(std::vector<T*>& dest,
template <class T>
static void resetlist(std::vector<T*>& list) {
for (auto element : list) {
element->id = -1;
}
list.clear();
}
mjCModel& mjCModel::operator+=(const mjCModel& other) { mjCModel& mjCModel::operator+=(const mjCModel& other) {
// create global lists // create global lists
MakeLists(bodies[0]); MakeLists(bodies[0]);
@@ -273,13 +283,85 @@ mjCModel& mjCModel::operator+=(const mjCModel& other) {
// restore to the same state as other // restore to the same state as other
if (!compiled) { if (!compiled) {
mjCBody* world = bodies[0]; mjCBody* world = bodies[0];
bodies.clear(); resetlist(bodies);
frames.clear(); resetlist(joints);
joints.clear(); resetlist(geoms);
geoms.clear(); resetlist(sites);
sites.clear(); resetlist(cameras);
cameras.clear(); resetlist(lights);
lights.clear(); resetlist(frames);
world->id = 0;
bodies.push_back(world);
}
PointToLocal();
return *this;
}
template <class T>
void mjCModel::RemoveFromList(std::vector<T*>& list, const mjCModel& other) {
int nlist = (int)list.size();
int removed = 0;
for (int i = 0; i < nlist; i++) {
T* element = list[i];
element->id -= removed;
try {
// check if the element contains an error
element->CopyFromSpec();
element->ResolveReferences(&other);
} catch (mjCError err) {
continue;
}
try {
// check if the element references something that was removed
element->ResolveReferences(this);
} catch (mjCError err) {
delete element;
list.erase(list.begin() + i);
nlist--;
i--;
removed++;
}
}
}
mjCModel& mjCModel::operator-=(const mjCBody& subtree) {
mjCModel oldmodel(*this);
oldmodel.MakeLists(oldmodel.bodies[0]);
oldmodel.CreateObjectLists();
oldmodel.ProcessLists();
// remove body from tree
*bodies[0] -= subtree;
// create global lists
MakeLists(bodies[0]);
CreateObjectLists();
ProcessLists();
// check if we have to remove anything else
RemoveFromList(pairs, oldmodel);
RemoveFromList(excludes, oldmodel);
RemoveFromList(tendons, oldmodel);
RemoveFromList(equalities, oldmodel);
RemoveFromList(actuators, oldmodel);
RemoveFromList(sensors, oldmodel);
// restore to the same state as before call
if (!compiled) {
mjCBody* world = bodies[0];
resetlist(bodies);
resetlist(joints);
resetlist(geoms);
resetlist(sites);
resetlist(cameras);
resetlist(lights);
resetlist(frames);
world->id = 0;
bodies.push_back(world); bodies.push_back(world);
} }
@@ -722,6 +804,9 @@ static T* findobject(std::string_view name, const vector<T*>& list, const mjKeyM
if (id == ids.end()) { if (id == ids.end()) {
return nullptr; return nullptr;
} }
if (id->second > (int)list.size() - 1) {
throw mjCError(0, "object not found");
}
return list[id->second]; return list[id->second];
} }
@@ -1985,7 +2070,7 @@ void mjCModel::CopyTree(mjModel* m) {
m->light_active[lid] = (mjtByte)pl->active; m->light_active[lid] = (mjtByte)pl->active;
copyvec(m->light_pos+3*lid, pl->pos, 3); copyvec(m->light_pos+3*lid, pl->pos, 3);
copyvec(m->light_dir+3*lid, pl->dir, 3); copyvec(m->light_dir+3*lid, pl->dir, 3);
m->light_radius[lid] = pl->radius; m->light_bulbradius[lid] = pl->bulbradius;
copyvec(m->light_attenuation+3*lid, pl->attenuation, 3); copyvec(m->light_attenuation+3*lid, pl->attenuation, 3);
m->light_cutoff[lid] = pl->cutoff; m->light_cutoff[lid] = pl->cutoff;
m->light_exponent[lid] = pl->exponent; m->light_exponent[lid] = pl->exponent;
@@ -2020,6 +2105,13 @@ void mjCModel::CopyTree(mjModel* m) {
} }
} }
// count bodies with gravity compensation, compute ngravcomp
int ngravcomp = 0;
for (int i=0; i<nbody; i++) {
ngravcomp += (m->body_gravcomp[i] > 0);
}
m->ngravcomp = ngravcomp;
// compute nM and dof_Madr // compute nM and dof_Madr
nM = 0; nM = 0;
for (int i=0; i<nv; i++) { for (int i=0; i<nv; i++) {
@@ -2402,6 +2494,8 @@ void mjCModel::CopyObjects(mjModel* m) {
m->mat_specular[i] = pmat->specular; m->mat_specular[i] = pmat->specular;
m->mat_shininess[i] = pmat->shininess; m->mat_shininess[i] = pmat->shininess;
m->mat_reflectance[i] = pmat->reflectance; m->mat_reflectance[i] = pmat->reflectance;
m->mat_metallic[i] = pmat->metallic;
m->mat_roughness[i] = pmat->roughness;
copyvec(m->mat_rgba+4*i, pmat->rgba, 4); copyvec(m->mat_rgba+4*i, pmat->rgba, 4);
} }
+7 -2
View File
@@ -158,12 +158,14 @@ class mjCModel : public mjCModel_, private mjSpec {
public: public:
mjCModel(); mjCModel();
mjCModel(const mjCModel& other); mjCModel(const mjCModel& other);
mjCModel& operator=(const mjCModel& other);
mjCModel& operator+=(const mjCModel& other);
~mjCModel(); ~mjCModel();
void CopyFromSpec(); // copy spec to private attributes void CopyFromSpec(); // copy spec to private attributes
void PointToLocal(); void PointToLocal();
mjCModel& operator=(const mjCModel& other); // copy other into this, if they are not the same
mjCModel& operator+=(const mjCModel& other); // add other into this, even if they are the same
mjCModel& operator-=(const mjCBody& subtree); // remove subtree and all references from model
mjSpec spec; mjSpec spec;
mjModel* Compile(const mjVFS* vfs = nullptr); // construct mjModel mjModel* Compile(const mjVFS* vfs = nullptr); // construct mjModel
@@ -196,6 +198,9 @@ class mjCModel : public mjCModel_, private mjSpec {
std::map<mjCDef*, int>& def_map, std::map<mjCDef*, int>& def_map,
const std::vector<mjCDef*>& defaults); const std::vector<mjCDef*>& defaults);
// delete from list the elements that are compatible with other but not this model
template <class T> void RemoveFromList(std::vector<T*>& list, const mjCModel& other);
// delete elements marked as discard=true // delete elements marked as discard=true
template <class T> void Delete(std::vector<T*>& elements, template <class T> void Delete(std::vector<T*>& elements,
const std::vector<bool>& discard); const std::vector<bool>& discard);
+15
View File
@@ -689,6 +689,7 @@ mjCBody& mjCBody::operator=(const mjCBody& other) {
sites.clear(); sites.clear();
cameras.clear(); cameras.clear();
lights.clear(); lights.clear();
id = other.id;
// add elements to lists // add elements to lists
*this += other; *this += other;
@@ -807,6 +808,20 @@ void mjCBody::CopyList(std::vector<T*>& dst, const std::vector<T*>& src,
// find and remove subtree
mjCBody& mjCBody::operator-=(const mjCBody& subtree) {
for (int i=0; i<bodies.size(); i++) {
if (bodies[i] == &subtree) {
bodies.erase(bodies.begin() + i);
break;
}
*bodies[i] -= subtree;
}
return *this;
}
void mjCBody::PointToLocal() { void mjCBody::PointToLocal() {
spec.element = static_cast<mjElement*>(this); spec.element = static_cast<mjElement*>(this);
spec.name = (mjString)&name; spec.name = (mjString)&name;
+5 -3
View File
@@ -263,6 +263,9 @@ class mjCBody : public mjCBody_, private mjsBody {
friend class mjXURDF; friend class mjXURDF;
public: public:
mjCBody(mjCModel*); // constructor
~mjCBody(); // destructor
// API for adding objects to body // API for adding objects to body
mjCBody* AddBody(mjCDef* = 0); mjCBody* AddBody(mjCDef* = 0);
mjCFrame* AddFrame(mjCFrame* = 0); mjCFrame* AddFrame(mjCFrame* = 0);
@@ -273,9 +276,10 @@ class mjCBody : public mjCBody_, private mjsBody {
mjCCamera* AddCamera(mjCDef* = 0); mjCCamera* AddCamera(mjCDef* = 0);
mjCLight* AddLight(mjCDef* = 0); mjCLight* AddLight(mjCDef* = 0);
// API for adding existing objects to body // API for adding/removing objects to body
mjCBody& operator+=(const mjCBody& other); mjCBody& operator+=(const mjCBody& other);
mjCBody& operator+=(const mjCFrame& other); mjCBody& operator+=(const mjCFrame& other);
mjCBody& operator-=(const mjCBody& subtree);
// API for accessing objects // API for accessing objects
int NumObjects(mjtObj type); int NumObjects(mjtObj type);
@@ -304,10 +308,8 @@ class mjCBody : public mjCBody_, private mjsBody {
const std::vector<double>& get_userdata() { return userdata_; } const std::vector<double>& get_userdata() { return userdata_; }
private: private:
mjCBody(mjCModel*); // constructor
mjCBody(const mjCBody& other, mjCModel* _model); // copy constructor mjCBody(const mjCBody& other, mjCModel* _model); // copy constructor
mjCBody& operator=(const mjCBody& other); // copy assignment mjCBody& operator=(const mjCBody& other); // copy assignment
~mjCBody(); // destructor
void Compile(void); // compiler void Compile(void); // compiler
void GeomFrame(void); // get inertial info from geoms void GeomFrame(void); // get inertial info from geoms
+10 -8
View File
@@ -136,8 +136,8 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
{"default", "R", "1", "class"}, {"default", "R", "1", "class"},
{"<"}, {"<"},
{"mesh", "?", "1", "scale"}, {"mesh", "?", "1", "scale"},
{"material", "?", "8", "texture", "emission", "specular", "shininess", {"material", "?", "10", "texture", "emission", "specular", "shininess",
"reflectance", "rgba", "texrepeat", "texuniform"}, "reflectance", "metallic", "roughness", "rgba", "texrepeat", "texuniform"},
{"joint", "?", "22", "type", "group", "pos", "axis", "springdamper", {"joint", "?", "22", "type", "group", "pos", "axis", "springdamper",
"limited", "actuatorfrclimited", "solreflimit", "solimplimit", "limited", "actuatorfrclimited", "solreflimit", "solimplimit",
"solreffriction", "solimpfriction", "stiffness", "range", "actuatorfrcrange", "solreffriction", "solimpfriction", "stiffness", "range", "actuatorfrcrange",
@@ -153,7 +153,7 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
{"camera", "?", "16", "fovy", "ipd", "resolution", "pos", "quat", "axisangle", "xyaxes", {"camera", "?", "16", "fovy", "ipd", "resolution", "pos", "quat", "axisangle", "xyaxes",
"zaxis", "euler", "mode", "focal", "focalpixel", "principal", "principalpixel", "zaxis", "euler", "mode", "focal", "focalpixel", "principal", "principalpixel",
"sensorsize", "user"}, "sensorsize", "user"},
{"light", "?", "13", "pos", "dir", "radius", "directional", "castshadow", "active", {"light", "?", "13", "pos", "dir", "bulbradius", "directional", "castshadow", "active",
"attenuation", "cutoff", "exponent", "ambient", "diffuse", "specular", "mode"}, "attenuation", "cutoff", "exponent", "ambient", "diffuse", "specular", "mode"},
{"pair", "?", "7", "condim", "friction", "solref", "solreffriction", "solimp", {"pair", "?", "7", "condim", "friction", "solref", "solreffriction", "solimp",
"gap", "margin"}, "gap", "margin"},
@@ -232,8 +232,8 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
"fileright", "fileleft", "fileup", "filedown", "filefront", "fileback", "fileright", "fileleft", "fileup", "filedown", "filefront", "fileback",
"builtin", "rgb1", "rgb2", "mark", "markrgb", "random", "width", "height", "builtin", "rgb1", "rgb2", "mark", "markrgb", "random", "width", "height",
"hflip", "vflip"}, "hflip", "vflip"},
{"material", "*", "10", "name", "class", "texture", "texrepeat", "texuniform", {"material", "*", "12", "name", "class", "texture", "texrepeat", "texuniform",
"emission", "specular", "shininess", "reflectance", "rgba"}, "emission", "specular", "shininess", "reflectance", "metallic", "roughness", "rgba"},
{">"}, {">"},
{"body", "R", "11", "name", "childclass", "pos", "quat", "mocap", {"body", "R", "11", "name", "childclass", "pos", "quat", "mocap",
@@ -264,7 +264,7 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
"axisangle", "xyaxes", "zaxis", "euler", "mode", "target", "focal", "focalpixel", "axisangle", "xyaxes", "zaxis", "euler", "mode", "target", "focal", "focalpixel",
"principal", "principalpixel", "sensorsize", "user"}, "principal", "principalpixel", "sensorsize", "user"},
{"light", "*", "16", "name", "class", "directional", "castshadow", "active", {"light", "*", "16", "name", "class", "directional", "castshadow", "active",
"pos", "dir", "radius", "attenuation", "cutoff", "exponent", "ambient", "diffuse", "pos", "dir", "bulbradius", "attenuation", "cutoff", "exponent", "ambient", "diffuse",
"specular", "mode", "target"}, "specular", "mode", "target"},
{"plugin", "*", "2", "plugin", "instance"}, {"plugin", "*", "2", "plugin", "instance"},
{"<"}, {"<"},
@@ -1186,7 +1186,7 @@ void mjXReader::Size(XMLElement* section, mjSpec* mod) {
}(); }();
if (memory.has_value()) { if (memory.has_value()) {
if (*memory / sizeof(mjtNum) > std::numeric_limits<int>::max()) { if (*memory / sizeof(mjtNum) > std::numeric_limits<std::size_t>::max()) {
throw mjXError(section, "%s", err_msg); throw mjXError(section, "%s", err_msg);
} }
mod->memory = *memory; mod->memory = *memory;
@@ -1530,6 +1530,8 @@ void mjXReader::OneMaterial(XMLElement* elem, mjsMaterial* pmat) {
ReadAttr(elem, "specular", 1, &pmat->specular, text); ReadAttr(elem, "specular", 1, &pmat->specular, text);
ReadAttr(elem, "shininess", 1, &pmat->shininess, text); ReadAttr(elem, "shininess", 1, &pmat->shininess, text);
ReadAttr(elem, "reflectance", 1, &pmat->reflectance, text); ReadAttr(elem, "reflectance", 1, &pmat->reflectance, text);
ReadAttr(elem, "metallic", 1, &pmat->metallic, text);
ReadAttr(elem, "roughness", 1, &pmat->roughness, text);
ReadAttr(elem, "rgba", 4, pmat->rgba, text); ReadAttr(elem, "rgba", 4, pmat->rgba, text);
// write error info // write error info
@@ -1783,7 +1785,7 @@ void mjXReader::OneLight(XMLElement* elem, mjsLight* plight) {
} }
ReadAttr(elem, "pos", 3, plight->pos, text); ReadAttr(elem, "pos", 3, plight->pos, text);
ReadAttr(elem, "dir", 3, plight->dir, text); ReadAttr(elem, "dir", 3, plight->dir, text);
ReadAttr(elem, "radius", 1, &plight->radius, text); ReadAttr(elem, "bulbradius", 1, &plight->bulbradius, text);
ReadAttr(elem, "attenuation", 3, plight->attenuation, text); ReadAttr(elem, "attenuation", 3, plight->attenuation, text);
ReadAttr(elem, "cutoff", 1, &plight->cutoff, text); ReadAttr(elem, "cutoff", 1, &plight->cutoff, text);
ReadAttr(elem, "exponent", 1, &plight->exponent, text); ReadAttr(elem, "exponent", 1, &plight->exponent, text);
+3 -1
View File
@@ -268,6 +268,8 @@ void mjXWriter::OneMaterial(XMLElement* elem, mjCMaterial* pmat, mjCDef* def) {
WriteAttr(elem, "specular", 1, &pmat->specular, &def->material.specular); WriteAttr(elem, "specular", 1, &pmat->specular, &def->material.specular);
WriteAttr(elem, "shininess", 1, &pmat->shininess, &def->material.shininess); WriteAttr(elem, "shininess", 1, &pmat->shininess, &def->material.shininess);
WriteAttr(elem, "reflectance", 1, &pmat->reflectance, &def->material.reflectance); WriteAttr(elem, "reflectance", 1, &pmat->reflectance, &def->material.reflectance);
WriteAttr(elem, "metallic", 1, &pmat->metallic, &def->material.metallic);
WriteAttr(elem, "roughness", 1, &pmat->roughness, &def->material.roughness);
WriteAttr(elem, "rgba", 4, pmat->rgba, def->material.rgba); WriteAttr(elem, "rgba", 4, pmat->rgba, def->material.rgba);
} }
@@ -508,7 +510,7 @@ void mjXWriter::OneLight(XMLElement* elem, mjCLight* plight, mjCDef* def) {
} }
// defaults and regular // defaults and regular
WriteAttr(elem, "radius", 1, &plight->radius, &def->light.radius); WriteAttr(elem, "bulbradius", 1, &plight->bulbradius, &def->light.bulbradius);
WriteAttrKey(elem, "directional", bool_map, 2, plight->directional, def->light.directional); WriteAttrKey(elem, "directional", bool_map, 2, plight->directional, def->light.directional);
WriteAttrKey(elem, "castshadow", bool_map, 2, plight->castshadow, def->light.castshadow); WriteAttrKey(elem, "castshadow", bool_map, 2, plight->castshadow, def->light.castshadow);
WriteAttrKey(elem, "active", bool_map, 2, plight->active, def->light.active); WriteAttrKey(elem, "active", bool_map, 2, plight->active, def->light.active);
+67
View File
@@ -667,6 +667,73 @@ TEST_F(EngineIoTest, CanMarkAndFreeStack) {
mj_deleteModel(model); mj_deleteModel(model);
} }
TEST_F(EngineIoTest, LargeMemory) {
constexpr char xml[] = R"(
<mujoco>
<size memory="2400M"/>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, NotNull()) << "Failed to load model: " << error.data();
mjData* data = mj_makeData(model);
ASSERT_THAT(data, NotNull());
// allocate 2.3G of mjtNums
mj_markStack(data);
size_t num = 2300000000 / sizeof(mjtNum);
mjtNum* testNum = mj_stackAllocNum(data, num);
testNum[num-1] = 1;
mj_freeStack(data);
// allocate 2.3G of bytes
mj_markStack(data);
num = 2300000000;
char* testByte = (char*) mj_stackAllocByte(data, num, alignof(char));
testByte[num-1] = 1;
mj_freeStack(data);
mj_deleteData(data);
mj_deleteModel(model);
}
TEST_F(EngineIoTest, VeryLargeMemory) {
constexpr char xml[] = R"(
<mujoco>
<size memory="64G"/>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
if (!model) {
// in some test environments, 64GB is too large
EXPECT_THAT(error.data(), HasSubstr("Could not allocate memory"));
} else {
ASSERT_THAT(model, NotNull()) << "Failed to load model: " << error.data();
mjData* data = mj_makeData(model);
ASSERT_THAT(data, NotNull());
// allocate 63G of mjtNums
mj_markStack(data);
size_t num = 63000000000 / sizeof(mjtNum);
mjtNum* testNum = mj_stackAllocNum(data, num);
testNum[num-1] = 1;
mj_freeStack(data);
// allocate 63G of bytes
mj_markStack(data);
num = 63000000000;
char* testByte = (char*) mj_stackAllocByte(data, num, alignof(char));
testByte[num-1] = 1;
mj_freeStack(data);
mj_deleteData(data);
mj_deleteModel(model);
}
}
struct TestFunctionArgs_ { struct TestFunctionArgs_ {
mjData* d; mjData* d;
int input; int input;
+49
View File
@@ -512,5 +512,54 @@ TEST_F(MujocoTest, AttachFrame) {
mj_deleteModel(m_expected); mj_deleteModel(m_expected);
} }
TEST_F(MujocoTest, DetachBody) {
std::array<char, 1000> er;
mjtNum tol = 0;
std::string field = "";
static constexpr char xml_result[] = R"(
<mujoco>
<worldbody>
<frame name="pframe">
<frame name="cframe">
</frame>
</frame>
<body name="ignore"/>
<frame name="frame" pos=".1 0 0" euler="0 90 0"/>
</worldbody>
<sensor>
<framepos name="ignore" objtype="body" objname="ignore"/>
</sensor>
</mujoco>)";
// model with one cylinder and a hinge
mjSpec* child = ParseSpecFromString(xml_child, er.data(), er.size());
EXPECT_THAT(child, NotNull()) << er.data();
// get subtree
mjsBody* body = mjs_findBody(child, "body");
EXPECT_THAT(body, NotNull());
// detach subtree
EXPECT_THAT(mjs_detachBody(child, body), 0);
// compile new model
mjModel* m_detached = mjs_compile(child, 0);
EXPECT_THAT(m_detached, NotNull());
// compare with expected XML
mjModel* m_expected = LoadModelFromString(xml_result, er.data(), er.size());
EXPECT_THAT(m_expected, NotNull()) << er.data();
EXPECT_LE(CompareModel(m_detached, m_expected, field), tol)
<< "Expected and attached models are different!\n"
<< "Different field: " << field << '\n';
// destroy everything
mjs_deleteSpec(child);
mjs_deleteBody(body);
mj_deleteModel(m_detached);
mj_deleteModel(m_expected);
}
} // namespace } // namespace
} // namespace mujoco } // namespace mujoco
+5 -5
View File
@@ -1873,22 +1873,22 @@ TEST_F(XMLReaderTest, LightRadius) {
<mujoco> <mujoco>
<default> <default>
<default class="r1"> <default class="r1">
<light radius="1"/> <light bulbradius="1"/>
</default> </default>
</default> </default>
<worldbody> <worldbody>
<light/> <light/>
<light class="r1"/> <light class="r1"/>
<light class="r1" radius="2"/> <light class="r1" bulbradius="2"/>
</worldbody> </worldbody>
</mujoco> </mujoco>
)"; )";
std::array<char, 1024> error; std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size()); mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, NotNull()) << error.data(); ASSERT_THAT(model, NotNull()) << error.data();
EXPECT_EQ(model->light_radius[0], 0); EXPECT_FLOAT_EQ(model->light_bulbradius[0], 0.02);
EXPECT_EQ(model->light_radius[1], 1); EXPECT_FLOAT_EQ(model->light_bulbradius[1], 1);
EXPECT_EQ(model->light_radius[2], 2); EXPECT_FLOAT_EQ(model->light_bulbradius[2], 2);
mj_deleteModel(model); mj_deleteModel(model);
} }
+35 -5
View File
@@ -943,13 +943,13 @@ TEST_F(XMLWriterTest, WritesLight) {
<mujoco> <mujoco>
<default> <default>
<default class="r1"> <default class="r1">
<light radius="1"/> <light bulbradius="1"/>
</default> </default>
</default> </default>
<worldbody> <worldbody>
<light/> <light/>
<light class="r1"/> <light class="r1"/>
<light class="r1" radius="2"/> <light class="r1" bulbradius="2"/>
</worldbody> </worldbody>
</mujoco> </mujoco>
)"; )";
@@ -959,9 +959,39 @@ TEST_F(XMLWriterTest, WritesLight) {
// save and read, compare data // save and read, compare data
mjModel* mtemp = LoadModelFromString(SaveAndReadXml(model)); mjModel* mtemp = LoadModelFromString(SaveAndReadXml(model));
EXPECT_EQ(mtemp->nlight, 3); EXPECT_EQ(mtemp->nlight, 3);
EXPECT_EQ(mtemp->light_radius[0], 0); EXPECT_FLOAT_EQ(mtemp->light_bulbradius[0], 0.02);
EXPECT_EQ(mtemp->light_radius[1], 1); EXPECT_FLOAT_EQ(mtemp->light_bulbradius[1], 1);
EXPECT_EQ(mtemp->light_radius[2], 2); EXPECT_FLOAT_EQ(mtemp->light_bulbradius[2], 2);
mj_deleteModel(mtemp);
mj_deleteModel(model);
}
TEST_F(XMLWriterTest, WritesMaterial) {
static constexpr char xml[] = R"(
<mujoco>
<default>
<default class="mat">
<material metallic="2" roughness="3"/>
</default>
</default>
<asset>
<material name="0" class="mat"/>
<material name="1" class="mat" metallic="4" roughness="5"/>
</asset>
</mujoco>
)";
std::array<char, 1000> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, NotNull()) << error.data();
// save and read, compare data
mjModel* mtemp = LoadModelFromString(SaveAndReadXml(model));
EXPECT_EQ(mtemp->nmat, 2);
EXPECT_EQ(mtemp->mat_metallic[0], 2);
EXPECT_EQ(mtemp->mat_metallic[1], 4);
EXPECT_EQ(mtemp->mat_roughness[0], 3);
EXPECT_EQ(mtemp->mat_roughness[1], 5);
mj_deleteModel(mtemp); mj_deleteModel(mtemp);
mj_deleteModel(model); mj_deleteModel(model);
+10 -3
View File
@@ -5163,6 +5163,7 @@ public unsafe struct mjModel_ {
public int nD; public int nD;
public int nB; public int nB;
public int ntree; public int ntree;
public int ngravcomp;
public int nemax; public int nemax;
public int njmax; public int njmax;
public int nconmax; public int nconmax;
@@ -5294,10 +5295,10 @@ public unsafe struct mjModel_ {
public int* light_targetbodyid; public int* light_targetbodyid;
public byte* light_directional; public byte* light_directional;
public byte* light_castshadow; public byte* light_castshadow;
public float* light_bulbradius;
public byte* light_active; public byte* light_active;
public double* light_pos; public double* light_pos;
public double* light_dir; public double* light_dir;
public double* light_radius;
public double* light_poscom0; public double* light_poscom0;
public double* light_pos0; public double* light_pos0;
public double* light_dir0; public double* light_dir0;
@@ -5420,6 +5421,8 @@ public unsafe struct mjModel_ {
public float* mat_specular; public float* mat_specular;
public float* mat_shininess; public float* mat_shininess;
public float* mat_reflectance; public float* mat_reflectance;
public float* mat_metallic;
public float* mat_roughness;
public float* mat_rgba; public float* mat_rgba;
public int* pair_dim; public int* pair_dim;
public int* pair_geom1; public int* pair_geom1;
@@ -5872,6 +5875,7 @@ public unsafe struct mjvLight_ {
public byte headlight; public byte headlight;
public byte directional; public byte directional;
public byte castshadow; public byte castshadow;
public float bulbradius;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
@@ -6149,6 +6153,7 @@ public unsafe struct model {
public float* cam_sensorsize; public float* cam_sensorsize;
public byte* light_directional; public byte* light_directional;
public byte* light_castshadow; public byte* light_castshadow;
public float* light_bulbradius;
public byte* light_active; public byte* light_active;
public float* light_attenuation; public float* light_attenuation;
public float* light_cutoff; public float* light_cutoff;
@@ -6210,6 +6215,8 @@ public unsafe struct model {
public float* mat_specular; public float* mat_specular;
public float* mat_shininess; public float* mat_shininess;
public float* mat_reflectance; public float* mat_reflectance;
public float* mat_metallic;
public float* mat_roughness;
public float* mat_rgba; public float* mat_rgba;
public int* eq_type; public int* eq_type;
public int* eq_obj1id; public int* eq_obj1id;
@@ -6424,10 +6431,10 @@ public static unsafe extern void mj_freeStack(mjData_* d);
public static unsafe extern void* mj_stackAllocByte(mjData_* d, UIntPtr bytes, UIntPtr alignment); public static unsafe extern void* mj_stackAllocByte(mjData_* d, UIntPtr bytes, UIntPtr alignment);
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)] [DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern double* mj_stackAllocNum(mjData_* d, int size); public static unsafe extern double* mj_stackAllocNum(mjData_* d, UIntPtr size);
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)] [DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern int* mj_stackAllocInt(mjData_* d, int size); public static unsafe extern int* mj_stackAllocInt(mjData_* d, UIntPtr size);
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)] [DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern void mj_deleteData(mjData_* d); public static unsafe extern void mj_deleteData(mjData_* d);