From cc78db41f442470a942c1ccc3fafb63c24b3a1f2 Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Mon, 22 Apr 2024 01:10:13 -0700 Subject: [PATCH 01/10] Add mjs_detachBody to C API. PiperOrigin-RevId: 626947850 Change-Id: I7c897048098ecd4f2247725ef2d378dbd00ef4a0 --- src/user/user_api.cc | 18 +++++++ src/user/user_api.h | 8 ++- src/user/user_model.cc | 99 +++++++++++++++++++++++++++++++++++--- src/user/user_model.h | 9 +++- src/user/user_objects.cc | 15 ++++++ src/user/user_objects.h | 8 +-- test/user/user_api_test.cc | 49 +++++++++++++++++++ 7 files changed, 193 insertions(+), 13 deletions(-) diff --git a/src/user/user_api.cc b/src/user/user_api.cc index f06d3de2..641afc89 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -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(s->element); + mjCBody* body = static_cast(b->element); + *model -= *body; + return 0; +} + + + // check if model has warnings int mjs_isWarning(mjSpec* s) { mjCModel* modelC = static_cast(s->element); @@ -126,6 +136,14 @@ void mjs_deleteSpec(mjSpec* s) { +// delete body +void mjs_deleteBody(mjsBody* b) { + mjCBody* body = static_cast(b->element); + delete body; +} + + + // add child body to body, return child spec mjsBody* mjs_addBody(mjsBody* bodyspec, mjsDefault* defspec) { mjCDef* def = defspec ? static_cast(defspec->element) : 0; diff --git a/src/user/user_api.h b/src/user/user_api.h index 0682191a..efb90e74 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -762,10 +762,13 @@ MJAPI void mjs_deleteSpec(mjSpec* s); MJAPI int mjs_attachBody(mjsFrame* parent, const mjsBody* child, 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, 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 --------------------------------------------- @@ -793,6 +796,9 @@ MJAPI mjsLight* mjs_addLight(mjsBody* body, mjsDefault* def); // Add frame to body. 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 ----------------------------------------- diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 20f81f32..45357e62 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -216,6 +216,16 @@ void mjCModel::CopyList(std::vector& dest, +template +static void resetlist(std::vector& list) { + for (auto element : list) { + element->id = -1; + } + list.clear(); +} + + + mjCModel& mjCModel::operator+=(const mjCModel& other) { // create global lists MakeLists(bodies[0]); @@ -273,13 +283,85 @@ mjCModel& mjCModel::operator+=(const mjCModel& other) { // restore to the same state as other if (!compiled) { mjCBody* world = bodies[0]; - bodies.clear(); - frames.clear(); - joints.clear(); - geoms.clear(); - sites.clear(); - cameras.clear(); - lights.clear(); + resetlist(bodies); + resetlist(joints); + resetlist(geoms); + resetlist(sites); + resetlist(cameras); + resetlist(lights); + resetlist(frames); + world->id = 0; + bodies.push_back(world); + } + + PointToLocal(); + return *this; +} + + + +template +void mjCModel::RemoveFromList(std::vector& 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); } @@ -722,6 +804,9 @@ static T* findobject(std::string_view name, const vector& list, const mjKeyM if (id == ids.end()) { return nullptr; } + if (id->second > (int)list.size() - 1) { + throw mjCError(0, "object not found"); + } return list[id->second]; } diff --git a/src/user/user_model.h b/src/user/user_model.h index 18d1607b..33fb50ca 100644 --- a/src/user/user_model.h +++ b/src/user/user_model.h @@ -158,12 +158,14 @@ class mjCModel : public mjCModel_, private mjSpec { public: mjCModel(); mjCModel(const mjCModel& other); - mjCModel& operator=(const mjCModel& other); - mjCModel& operator+=(const mjCModel& other); ~mjCModel(); void CopyFromSpec(); // copy spec to private attributes 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; mjModel* Compile(const mjVFS* vfs = nullptr); // construct mjModel @@ -196,6 +198,9 @@ class mjCModel : public mjCModel_, private mjSpec { std::map& def_map, const std::vector& defaults); + // delete from list the elements that are compatible with other but not this model + template void RemoveFromList(std::vector& list, const mjCModel& other); + // delete elements marked as discard=true template void Delete(std::vector& elements, const std::vector& discard); diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index eb24e2b1..abe94ae0 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -689,6 +689,7 @@ mjCBody& mjCBody::operator=(const mjCBody& other) { sites.clear(); cameras.clear(); lights.clear(); + id = other.id; // add elements to lists *this += other; @@ -807,6 +808,20 @@ void mjCBody::CopyList(std::vector& dst, const std::vector& src, +// find and remove subtree +mjCBody& mjCBody::operator-=(const mjCBody& subtree) { + for (int i=0; i(this); spec.name = (mjString)&name; diff --git a/src/user/user_objects.h b/src/user/user_objects.h index f6e91a81..a073157f 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -263,6 +263,9 @@ class mjCBody : public mjCBody_, private mjsBody { friend class mjXURDF; public: + mjCBody(mjCModel*); // constructor + ~mjCBody(); // destructor + // API for adding objects to body mjCBody* AddBody(mjCDef* = 0); mjCFrame* AddFrame(mjCFrame* = 0); @@ -273,9 +276,10 @@ class mjCBody : public mjCBody_, private mjsBody { mjCCamera* AddCamera(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 mjCFrame& other); + mjCBody& operator-=(const mjCBody& subtree); // API for accessing objects int NumObjects(mjtObj type); @@ -304,10 +308,8 @@ class mjCBody : public mjCBody_, private mjsBody { const std::vector& get_userdata() { return userdata_; } private: - mjCBody(mjCModel*); // constructor mjCBody(const mjCBody& other, mjCModel* _model); // copy constructor mjCBody& operator=(const mjCBody& other); // copy assignment - ~mjCBody(); // destructor void Compile(void); // compiler void GeomFrame(void); // get inertial info from geoms diff --git a/test/user/user_api_test.cc b/test/user/user_api_test.cc index 3e712310..45554f90 100644 --- a/test/user/user_api_test.cc +++ b/test/user/user_api_test.cc @@ -512,5 +512,54 @@ TEST_F(MujocoTest, AttachFrame) { mj_deleteModel(m_expected); } +TEST_F(MujocoTest, DetachBody) { + std::array er; + mjtNum tol = 0; + std::string field = ""; + + static constexpr char xml_result[] = R"( + + + + + + + + + + + + + )"; + + // 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 mujoco From 9aa885aa632a5779c870bed3bf87ba7e442a4512 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Mon, 22 Apr 2024 04:35:42 -0700 Subject: [PATCH 02/10] Fix attribute order in mjsDefault. PiperOrigin-RevId: 626992244 Change-Id: I0755745d2d4a55fbf6c685ad383a5be0842e7984 --- src/user/user_api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user/user_api.h b/src/user/user_api.h index efb90e74..bd2dc044 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -715,8 +715,8 @@ typedef struct _mjsKey { // keyframe specification typedef struct _mjsDefault { // default specification - mjString name; // name mjElement* element; // element type + mjString name; // class name mjsJoint* joint; // joint defaults mjsGeom* geom; // geom defaults mjsSite* site; // site defaults From c2d0c5dd1bcee3dc132779610e6e87f0da2db615 Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Mon, 22 Apr 2024 05:06:35 -0700 Subject: [PATCH 03/10] Add cylinder collisions using SDFs. PiperOrigin-RevId: 626998709 Change-Id: I669a639b1cabf5ed522c73a07e54684d675fa396 --- doc/changelog.rst | 7 +- mjx/mujoco/mjx/_src/collision_driver.py | 6 ++ mjx/mujoco/mjx/_src/collision_driver_test.py | 23 +++++ mjx/mujoco/mjx/_src/collision_sdf.py | 99 ++++++++++++++++++-- 4 files changed, 123 insertions(+), 12 deletions(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index 010fa6f3..7d0ecc4c 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -31,12 +31,13 @@ MJX 9. Changed the way meshes are organized on device to speed up collision detection when a mesh is replicated for many geoms. 10. Fixed a bug where capsules might be ignored in broadphase colliision checking. +11. Added cylinder collisions using SDFs. Bug fixes ^^^^^^^^^ -11. 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. -13. Fixed bug in Python binding of :ref:`mj_saveModel`: ``buffer`` argument was documented as optional but was actually +12. Defaults of lights were not being saved, now fixed. +13. Prevent overwriting of frame names by body names when saving an XML. Introduced in 3.1.4. +14. Fixed bug in Python binding of :ref:`mj_saveModel`: ``buffer`` argument was documented as optional but was actually not optional. diff --git a/mjx/mujoco/mjx/_src/collision_driver.py b/mjx/mujoco/mjx/_src/collision_driver.py index c68e0edd..b59fe1a8 100644 --- a/mjx/mujoco/mjx/_src/collision_driver.py +++ b/mjx/mujoco/mjx/_src/collision_driver.py @@ -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 sphere_capsule 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 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_types import FunctionKey from mujoco.mjx._src.types import Contact @@ -82,8 +85,11 @@ _COLLISION_FUNC = { (GeomType.CAPSULE, GeomType.CAPSULE): capsule_capsule, (GeomType.CAPSULE, GeomType.BOX): capsule_convex, (GeomType.CAPSULE, GeomType.ELLIPSOID): capsule_ellipsoid, + (GeomType.CAPSULE, GeomType.CYLINDER): capsule_cylinder, (GeomType.CAPSULE, GeomType.MESH): capsule_convex, (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.MESH): convex_convex, (GeomType.MESH, GeomType.MESH): convex_convex, diff --git a/mjx/mujoco/mjx/_src/collision_driver_test.py b/mjx/mujoco/mjx/_src/collision_driver_test.py index c1d77e99..afc076f7 100644 --- a/mjx/mujoco/mjx/_src/collision_driver_test.py +++ b/mjx/mujoco/mjx/_src/collision_driver_test.py @@ -264,6 +264,29 @@ class EllipsoidCollisionTest(parameterized.TestCase): _assert_attr_eq( dx.contact, d.contact, field.name, 'ellipsoid-capsule', 1e-4) + _ELLIPSOID_CYLINDER = """ + + + + + + + + + + + + """ + + 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): _CAP_PLANE = """ diff --git a/mjx/mujoco/mjx/_src/collision_sdf.py b/mjx/mujoco/mjx/_src/collision_sdf.py index 85481245..68164a32 100644 --- a/mjx/mujoco/mjx/_src/collision_sdf.py +++ b/mjx/mujoco/mjx/_src/collision_sdf.py @@ -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) +@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: return lambda p: f(mat.T @ (p - pos)) @@ -134,29 +171,73 @@ def _gradient_descent( def _optim( - d1, d2, info1: GeomInfo, info2: GeomInfo -) -> Tuple[jax.Array, jax.Array, jax.Array]: + d1, d2, info1: GeomInfo, info2: GeomInfo, x0: jax.Array, +) -> Collision: """Optimizes the clearance function.""" d1 = functools.partial(d1, size=info1.size) d1 = _to_local(d1, info1.pos, info1.mat) d2 = functools.partial(d2, size=info2.size) d2 = _to_local(d2, info2.pos, info2.mat) 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) - n = jax.grad(d1)(pos) - return pos, dist, n + n = jax.grad(d1)(pos) - jax.grad(d2)(pos) + return dist, pos, math.make_frame(n) @collider(ncon=1) def capsule_ellipsoid(c: GeomInfo, e: GeomInfo) -> Collision: """"Calculates contact between a capsule and an ellipsoid.""" - pos, dist, n = _optim(_capsule, _ellipsoid, c, e) - return dist, pos, math.make_frame(n) + x0 = 0.5 * (c.pos + e.pos) + 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) def ellipsoid_ellipsoid(e1: GeomInfo, e2: GeomInfo) -> Collision: """"Calculates contact between two ellipsoids.""" - pos, dist, n = _optim(_ellipsoid, _ellipsoid, e1, e2) - return dist, pos, math.make_frame(n) + x0 = 0.5 * (e1.pos + e2.pos) + 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) + From caf215e3423c4a4d5e1a760972f36a24bf08c3dc Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Mon, 22 Apr 2024 07:37:52 -0700 Subject: [PATCH 04/10] Add metallic and roughness scalar attributes to materials. Rename `light_radius` -> `light_bulbradius`, make the default value 0.02. PiperOrigin-RevId: 627032170 Change-Id: I1e01e2eca028c0aefc2e7dc384e8b34abac184aa --- doc/XMLreference.rst | 30 ++++++++++++---- doc/XMLschema.rst | 10 +++--- doc/changelog.rst | 10 ++++-- doc/includes/references.h | 8 ++++- include/mujoco/mjmodel.h | 4 ++- include/mujoco/mjvisualize.h | 4 +++ include/mujoco/mjxmacro.h | 4 ++- introspect/structs.py | 54 ++++++++++++++++++++++++---- python/mujoco/structs.cc | 1 + src/engine/engine_vis_visualize.c | 1 + src/user/user_api.h | 4 ++- src/user/user_init.cc | 3 ++ src/user/user_model.cc | 4 ++- src/xml/xml_native_reader.cc | 16 +++++---- src/xml/xml_native_writer.cc | 4 ++- test/xml/xml_native_reader_test.cc | 10 +++--- test/xml/xml_native_writer_test.cc | 40 ++++++++++++++++++--- unity/Runtime/Bindings/MjBindings.cs | 8 ++++- 18 files changed, 170 insertions(+), 45 deletions(-) diff --git a/doc/XMLreference.rst b/doc/XMLreference.rst index 90e8f04a..44230bb8 100644 --- a/doc/XMLreference.rst +++ b/doc/XMLreference.rst @@ -1788,6 +1788,18 @@ properties are grouped together. instead. Only the first reflective geom in the model is rendered as such. This adds one extra rendering pass through all geoms, in addition to the extra rendering pass added by each shadow-casting light. +.. _asset-material-metallic: + +:at:`metallic`: :at-val:`real, "0"` + This attribute corresponds to uniform metallicity coefficient applied to the entire material. This attribute has no + effect in MuJoCo's native renderer, but it can be useful when rendering scenes with an external renderer. + +.. _asset-material-roughness: + +:at:`roughness`: :at-val:`real, "1"` + This attribute corresponds to uniform roughness coefficient applied to the entire material. This attribute has no + effect in MuJoCo's native renderer, but it can be useful when rendering scenes with an external renderer. + .. _asset-material-rgba: :at:`rgba`: :at-val:`real(4), "1 1 1 1"` @@ -3165,6 +3177,12 @@ the direction specified by the dir attribute. It does not have a full spatial fr these clipping planes bound the cone or box shadow volume in the light direction. As a result, some shadows (especially those very close to the light) may be clipped. +.. _body-light-bulbradius: + +:at:`radius`: :at-val:`real, "0.02"` + Radius of the light, affects shadow softness. This attribute has no effect in MuJoCo's native renderer, but it can be + useful when rendering scenes with an external renderer. + .. _body-light-active: :at:`active`: :at-val:`[false, true], "true"` @@ -3181,12 +3199,6 @@ the direction specified by the dir attribute. It does not have a full spatial fr :at:`dir`: :at-val:`real(3), "0 0 -1"` Direction of the light. -.. _body-light-radius: - -:at:`radius`: :at-val:`real, "0"` - Radius of the light, affects shadow softness. This attribute has no effect in MuJoCo's native renderer, but it can be - useful when rendering scenes with an external renderer. - .. _body-light-attenuation: :at:`attenuation`: :at-val:`real(3), "1 0 0"` @@ -7372,6 +7384,10 @@ if omitted. .. _default-material-reflectance: +.. _default-material-metallic: + +.. _default-material-roughness: + .. _default-material-rgba: .. _default-material-texrepeat: @@ -7592,7 +7608,7 @@ if omitted. .. _default-light-dir: -.. _default-light-radius: +.. _default-light-bulbradius: .. _default-light-directional: diff --git a/doc/XMLschema.rst b/doc/XMLschema.rst index c374cfa0..236ab005 100644 --- a/doc/XMLschema.rst +++ b/doc/XMLschema.rst @@ -213,7 +213,7 @@ | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | | :ref:`texuniform` | :ref:`emission` | :ref:`specular` | :ref:`shininess` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`reflectance` | :ref:`rgba` | | | | +| | | | :ref:`reflectance` | :ref:`metallic` | :ref:`roughness` | :ref:`rgba` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | mujoco |br| |L| | | .. table:: | @@ -369,7 +369,7 @@ | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | | :ref:`name` | :ref:`class` | :ref:`directional` | :ref:`castshadow` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`active` | :ref:`pos` | :ref:`dir` | :ref:`radius` | | +| | | | :ref:`active` | :ref:`pos` | :ref:`dir` | :ref:`bulbradius` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | | :ref:`attenuation` | :ref:`cutoff` | :ref:`exponent` | :ref:`ambient` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | @@ -1307,7 +1307,9 @@ | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | | :ref:`texture` | :ref:`emission` | :ref:`specular` | :ref:`shininess` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`reflectance` | :ref:`rgba` | :ref:`texrepeat` | :ref:`texuniform` | | +| | | | :ref:`reflectance` | :ref:`metallic` | :ref:`roughness` | :ref:`rgba` | | +| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | +| | | | :ref:`texrepeat` | :ref:`texuniform` | | | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | |_| default |br| |_| |L| | | .. table:: | @@ -1378,7 +1380,7 @@ | :ref:`light | ? | :class: mjcf-attributes | | ` | | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`pos` | :ref:`dir` | :ref:`radius` | :ref:`directional` | | +| | | | :ref:`pos` | :ref:`dir` | :ref:`bulbradius` | :ref:`directional` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | | :ref:`castshadow` | :ref:`active` | :ref:`attenuation` | :ref:`cutoff` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | diff --git a/doc/changelog.rst b/doc/changelog.rst index 7d0ecc4c..9b9b8a7a 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -9,8 +9,12 @@ General ^^^^^^^ 1. Added ``mjModel.mesh_scale``: the scaling applied to asset vertices, as specified in the :ref:`scale` attribute. -2. Added the :ref:`light/radius` attribute and corresponding ``mjModel.light_radius`` field. This - value has no effect in MuJoCo's native renderer, but can be usful when rendering scenes with an external renderer. +2. Added visual properties which are ignored by the native renderer, but can be used by external renderers: + + - :ref:`light/bulbradius` attribute and corresponding ``mjModel.light_bulbradius`` field. + - :ref:`material/metallic` attribute and corresponding ``mjModel.material_metallic`` field. + - :ref:`material/roughness` attribute and corresponding ``mjModel.material_roughness`` + field. MJX ^^^ @@ -36,7 +40,7 @@ MJX Bug fixes ^^^^^^^^^ 12. Defaults of lights were not being saved, now fixed. -13. Prevent overwriting of frame names by body names when saving an XML. Introduced in 3.1.4. +13. Prevent overwriting of frame names by body names when saving an XML. Bug introduced in 3.1.4. 14. Fixed bug in Python binding of :ref:`mj_saveModel`: ``buffer`` argument was documented as optional but was actually not optional. diff --git a/doc/includes/references.h b/doc/includes/references.h index e0a77d94..8a59d8c3 100644 --- a/doc/includes/references.h +++ b/doc/includes/references.h @@ -1079,10 +1079,10 @@ struct mjModel_ { int* light_targetbodyid; // id of targeted body; -1: none (nlight x 1) mjtByte* light_directional; // directional light (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) mjtNum* light_pos; // position 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_pos0; // global position rel. to body in qpos0 (nlight x 3) mjtNum* light_dir0; // global direction in qpos0 (nlight x 3) @@ -1219,6 +1219,8 @@ struct mjModel_ { float* mat_specular; // specular (x white) (nmat x 1) float* mat_shininess; // shininess coef (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) // predefined geom pairs for collision detection; has precedence over exclude @@ -2022,6 +2024,7 @@ struct mjvLight_ { // OpenGL light mjtByte headlight; // headlight mjtByte directional; // directional light mjtByte castshadow; // does light cast shadows + float bulbradius; // bulb radius for soft shadows }; typedef struct mjvLight_ mjvLight; struct mjvOption_ { // abstract visualization options @@ -2236,6 +2239,7 @@ struct mjvSceneState_ { mjtByte* light_directional; mjtByte* light_castshadow; + float* light_bulbradius; mjtByte* light_active; float* light_attenuation; float* light_cutoff; @@ -2303,6 +2307,8 @@ struct mjvSceneState_ { float* mat_specular; float* mat_shininess; float* mat_reflectance; + float* mat_metallic; + float* mat_roughness; float* mat_rgba; int* eq_type; diff --git a/include/mujoco/mjmodel.h b/include/mujoco/mjmodel.h index 37e2a9f4..79ec6ad9 100644 --- a/include/mujoco/mjmodel.h +++ b/include/mujoco/mjmodel.h @@ -794,10 +794,10 @@ struct mjModel_ { int* light_targetbodyid; // id of targeted body; -1: none (nlight x 1) mjtByte* light_directional; // directional light (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) mjtNum* light_pos; // position 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_pos0; // global position rel. to body in qpos0 (nlight x 3) mjtNum* light_dir0; // global direction in qpos0 (nlight x 3) @@ -934,6 +934,8 @@ struct mjModel_ { float* mat_specular; // specular (x white) (nmat x 1) float* mat_shininess; // shininess coef (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) // predefined geom pairs for collision detection; has precedence over exclude diff --git a/include/mujoco/mjvisualize.h b/include/mujoco/mjvisualize.h index dc8a4bc6..350f9c1e 100644 --- a/include/mujoco/mjvisualize.h +++ b/include/mujoco/mjvisualize.h @@ -263,6 +263,7 @@ struct mjvLight_ { // OpenGL light mjtByte headlight; // headlight mjtByte directional; // directional light mjtByte castshadow; // does light cast shadows + float bulbradius; // bulb radius for soft shadows }; typedef struct mjvLight_ mjvLight; @@ -493,6 +494,7 @@ struct mjvSceneState_ { mjtByte* light_directional; mjtByte* light_castshadow; + float* light_bulbradius; mjtByte* light_active; float* light_attenuation; float* light_cutoff; @@ -560,6 +562,8 @@ struct mjvSceneState_ { float* mat_specular; float* mat_shininess; float* mat_reflectance; + float* mat_metallic; + float* mat_roughness; float* mat_rgba; int* eq_type; diff --git a/include/mujoco/mjxmacro.h b/include/mujoco/mjxmacro.h index 6ad3093b..daf1d30b 100644 --- a/include/mujoco/mjxmacro.h +++ b/include/mujoco/mjxmacro.h @@ -292,10 +292,10 @@ X ( int, light_targetbodyid, nlight, 1 ) \ XMJV( mjtByte, light_directional, nlight, 1 ) \ XMJV( mjtByte, light_castshadow, nlight, 1 ) \ + XMJV( float, light_bulbradius, nlight, 1 ) \ XMJV( mjtByte, light_active, nlight, 1 ) \ X ( mjtNum, light_pos, nlight, 3 ) \ X ( mjtNum, light_dir, nlight, 3 ) \ - X ( mjtNum, light_radius, nlight, 1 ) \ X ( mjtNum, light_poscom0, nlight, 3 ) \ X ( mjtNum, light_pos0, nlight, 3 ) \ X ( mjtNum, light_dir0, nlight, 3 ) \ @@ -418,6 +418,8 @@ XMJV( float, mat_specular, nmat, 1 ) \ XMJV( float, mat_shininess, 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 ) \ X ( int, pair_dim, npair, 1 ) \ X ( int, pair_geom1, npair, 1 ) \ diff --git a/introspect/structs.py b/introspect/structs.py index 112cb730..45199a98 100644 --- a/introspect/structs.py +++ b/introspect/structs.py @@ -2095,6 +2095,13 @@ STRUCTS: Mapping[str, StructDecl] = dict([ ), 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( name='light_active', type=PointerType( @@ -2116,13 +2123,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([ ), 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( name='light_poscom0', type=PointerType( @@ -2977,6 +2977,20 @@ STRUCTS: Mapping[str, StructDecl] = dict([ ), 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( name='mat_rgba', type=PointerType( @@ -5624,6 +5638,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([ type=ValueType(name='mjtByte'), doc='does light cast shadows', ), + StructFieldDecl( + name='bulbradius', + type=ValueType(name='float'), + doc='bulb radius for soft shadows', + ), ), )), ('mjvOption', @@ -6719,6 +6738,13 @@ STRUCTS: Mapping[str, StructDecl] = dict([ ), doc='', ), + StructFieldDecl( + name='light_bulbradius', + type=PointerType( + inner_type=ValueType(name='float'), + ), + doc='', + ), StructFieldDecl( name='light_active', type=PointerType( @@ -7146,6 +7172,20 @@ STRUCTS: Mapping[str, StructDecl] = dict([ ), 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( name='mat_rgba', type=PointerType( diff --git a/python/mujoco/structs.cc b/python/mujoco/structs.cc index 40457f04..ebe134a8 100644 --- a/python/mujoco/structs.cc +++ b/python/mujoco/structs.cc @@ -2226,6 +2226,7 @@ This is useful for example when the MJB is not available as a file on disk.)")); X(headlight); X(directional); X(castshadow); + X(bulbradius); #undef X #define X(var) DefinePyArray(mjvLight, #var, &MjvLightWrapper::var) diff --git a/src/engine/engine_vis_visualize.c b/src/engine/engine_vis_visualize.c index 74bd9cd5..5de671f1 100644 --- a/src/engine/engine_vis_visualize.c +++ b/src/engine/engine_vis_visualize.c @@ -2091,6 +2091,7 @@ void mjv_makeLights(const mjModel* m, mjData* d, mjvScene* scn) { memset(thislight, 0, sizeof(mjvLight)); thislight->directional = m->light_directional[i]; thislight->castshadow = m->light_castshadow[i]; + thislight->bulbradius = m->light_bulbradius[i]; if (!thislight->directional) { f2f(thislight->attenuation, m->light_attenuation+3*i, 3); thislight->exponent = m->light_exponent[i]; diff --git a/src/user/user_api.h b/src/user/user_api.h index bd2dc044..7361ff86 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -347,7 +347,6 @@ typedef struct _mjsLight { // light specification // frame double pos[3]; // position double dir[3]; // direction - double radius; // radius mjtCamLight mode; // tracking mode mjString targetbody; // target body for targeting @@ -355,6 +354,7 @@ typedef struct _mjsLight { // light specification mjtByte active; // is light active mjtByte directional; // is light directional or spot mjtByte castshadow; // does light cast shadows + double bulbradius; // bulb radius, for soft shadows float attenuation[3]; // OpenGL attenuation (quadratic model) float cutoff; // OpenGL cutoff float exponent; // OpenGL exponent @@ -515,6 +515,8 @@ typedef struct _mjsMaterial { // material specification float specular; // specular float shininess; // shininess float reflectance; // reflectance + float metallic; // metallic + float roughness; // roughness float rgba[4]; // rgba mjString info; // message appended to compiler errors } mjsMaterial; diff --git a/src/user/user_init.cc b/src/user/user_init.cc index b9553933..4fc27110 100644 --- a/src/user/user_init.cc +++ b/src/user/user_init.cc @@ -218,6 +218,7 @@ void mjs_defaultLight(mjsLight& light) { // intrinsics light.castshadow = 1; + light.bulbradius = 0.02; light.active = 1; light.dir[2] = -1; light.attenuation[0] = 1; @@ -305,6 +306,8 @@ void mjs_defaultMaterial(mjsMaterial& material) { material.specular = 0.5; material.shininess = 0.5; material.reflectance = 0; + material.metallic = 1.0; + material.roughness = 1.0; material.rgba[0] = material.rgba[1] = material.rgba[2] = material.rgba[3] = 1; } diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 45357e62..5abf4163 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -2070,7 +2070,7 @@ void mjCModel::CopyTree(mjModel* m) { m->light_active[lid] = (mjtByte)pl->active; copyvec(m->light_pos+3*lid, pl->pos, 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); m->light_cutoff[lid] = pl->cutoff; m->light_exponent[lid] = pl->exponent; @@ -2487,6 +2487,8 @@ void mjCModel::CopyObjects(mjModel* m) { m->mat_specular[i] = pmat->specular; m->mat_shininess[i] = pmat->shininess; 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); } diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index 7427f019..334adebe 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -136,8 +136,8 @@ const char* MJCF[nMJCF][mjXATTRNUM] = { {"default", "R", "1", "class"}, {"<"}, {"mesh", "?", "1", "scale"}, - {"material", "?", "8", "texture", "emission", "specular", "shininess", - "reflectance", "rgba", "texrepeat", "texuniform"}, + {"material", "?", "10", "texture", "emission", "specular", "shininess", + "reflectance", "metallic", "roughness", "rgba", "texrepeat", "texuniform"}, {"joint", "?", "22", "type", "group", "pos", "axis", "springdamper", "limited", "actuatorfrclimited", "solreflimit", "solimplimit", "solreffriction", "solimpfriction", "stiffness", "range", "actuatorfrcrange", @@ -153,7 +153,7 @@ const char* MJCF[nMJCF][mjXATTRNUM] = { {"camera", "?", "16", "fovy", "ipd", "resolution", "pos", "quat", "axisangle", "xyaxes", "zaxis", "euler", "mode", "focal", "focalpixel", "principal", "principalpixel", "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"}, {"pair", "?", "7", "condim", "friction", "solref", "solreffriction", "solimp", "gap", "margin"}, @@ -232,8 +232,8 @@ const char* MJCF[nMJCF][mjXATTRNUM] = { "fileright", "fileleft", "fileup", "filedown", "filefront", "fileback", "builtin", "rgb1", "rgb2", "mark", "markrgb", "random", "width", "height", "hflip", "vflip"}, - {"material", "*", "10", "name", "class", "texture", "texrepeat", "texuniform", - "emission", "specular", "shininess", "reflectance", "rgba"}, + {"material", "*", "12", "name", "class", "texture", "texrepeat", "texuniform", + "emission", "specular", "shininess", "reflectance", "metallic", "roughness", "rgba"}, {">"}, {"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", "principal", "principalpixel", "sensorsize", "user"}, {"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"}, {"plugin", "*", "2", "plugin", "instance"}, {"<"}, @@ -1530,6 +1530,8 @@ void mjXReader::OneMaterial(XMLElement* elem, mjsMaterial* pmat) { ReadAttr(elem, "specular", 1, &pmat->specular, text); ReadAttr(elem, "shininess", 1, &pmat->shininess, 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); // write error info @@ -1783,7 +1785,7 @@ void mjXReader::OneLight(XMLElement* elem, mjsLight* plight) { } ReadAttr(elem, "pos", 3, plight->pos, 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, "cutoff", 1, &plight->cutoff, text); ReadAttr(elem, "exponent", 1, &plight->exponent, text); diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc index cfbdfee4..2e729966 100644 --- a/src/xml/xml_native_writer.cc +++ b/src/xml/xml_native_writer.cc @@ -268,6 +268,8 @@ void mjXWriter::OneMaterial(XMLElement* elem, mjCMaterial* pmat, mjCDef* def) { WriteAttr(elem, "specular", 1, &pmat->specular, &def->material.specular); WriteAttr(elem, "shininess", 1, &pmat->shininess, &def->material.shininess); 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); } @@ -508,7 +510,7 @@ void mjXWriter::OneLight(XMLElement* elem, mjCLight* plight, mjCDef* def) { } // 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, "castshadow", bool_map, 2, plight->castshadow, def->light.castshadow); WriteAttrKey(elem, "active", bool_map, 2, plight->active, def->light.active); diff --git a/test/xml/xml_native_reader_test.cc b/test/xml/xml_native_reader_test.cc index 61253f35..5b800405 100644 --- a/test/xml/xml_native_reader_test.cc +++ b/test/xml/xml_native_reader_test.cc @@ -1873,22 +1873,22 @@ TEST_F(XMLReaderTest, LightRadius) { - + - + )"; std::array error; mjModel* model = LoadModelFromString(xml, error.data(), error.size()); ASSERT_THAT(model, NotNull()) << error.data(); - EXPECT_EQ(model->light_radius[0], 0); - EXPECT_EQ(model->light_radius[1], 1); - EXPECT_EQ(model->light_radius[2], 2); + EXPECT_FLOAT_EQ(model->light_bulbradius[0], 0.02); + EXPECT_FLOAT_EQ(model->light_bulbradius[1], 1); + EXPECT_FLOAT_EQ(model->light_bulbradius[2], 2); mj_deleteModel(model); } diff --git a/test/xml/xml_native_writer_test.cc b/test/xml/xml_native_writer_test.cc index e86e3254..92131025 100644 --- a/test/xml/xml_native_writer_test.cc +++ b/test/xml/xml_native_writer_test.cc @@ -943,13 +943,13 @@ TEST_F(XMLWriterTest, WritesLight) { - + - + )"; @@ -959,9 +959,39 @@ TEST_F(XMLWriterTest, WritesLight) { // save and read, compare data mjModel* mtemp = LoadModelFromString(SaveAndReadXml(model)); EXPECT_EQ(mtemp->nlight, 3); - EXPECT_EQ(mtemp->light_radius[0], 0); - EXPECT_EQ(mtemp->light_radius[1], 1); - EXPECT_EQ(mtemp->light_radius[2], 2); + EXPECT_FLOAT_EQ(mtemp->light_bulbradius[0], 0.02); + EXPECT_FLOAT_EQ(mtemp->light_bulbradius[1], 1); + EXPECT_FLOAT_EQ(mtemp->light_bulbradius[2], 2); + + mj_deleteModel(mtemp); + mj_deleteModel(model); +} + +TEST_F(XMLWriterTest, WritesMaterial) { + static constexpr char xml[] = R"( + + + + + + + + + + + + )"; + std::array 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(model); diff --git a/unity/Runtime/Bindings/MjBindings.cs b/unity/Runtime/Bindings/MjBindings.cs index 4b8d6f84..28a0d0d8 100644 --- a/unity/Runtime/Bindings/MjBindings.cs +++ b/unity/Runtime/Bindings/MjBindings.cs @@ -5294,10 +5294,10 @@ public unsafe struct mjModel_ { public int* light_targetbodyid; public byte* light_directional; public byte* light_castshadow; + public float* light_bulbradius; public byte* light_active; public double* light_pos; public double* light_dir; - public double* light_radius; public double* light_poscom0; public double* light_pos0; public double* light_dir0; @@ -5420,6 +5420,8 @@ public unsafe struct mjModel_ { public float* mat_specular; public float* mat_shininess; public float* mat_reflectance; + public float* mat_metallic; + public float* mat_roughness; public float* mat_rgba; public int* pair_dim; public int* pair_geom1; @@ -5872,6 +5874,7 @@ public unsafe struct mjvLight_ { public byte headlight; public byte directional; public byte castshadow; + public float bulbradius; } [StructLayout(LayoutKind.Sequential)] @@ -6149,6 +6152,7 @@ public unsafe struct model { public float* cam_sensorsize; public byte* light_directional; public byte* light_castshadow; + public float* light_bulbradius; public byte* light_active; public float* light_attenuation; public float* light_cutoff; @@ -6210,6 +6214,8 @@ public unsafe struct model { public float* mat_specular; public float* mat_shininess; public float* mat_reflectance; + public float* mat_metallic; + public float* mat_roughness; public float* mat_rgba; public int* eq_type; public int* eq_obj1id; From 6540289eb17beea4c6800bf5e1eb4f20b1913796 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Mon, 22 Apr 2024 07:55:33 -0700 Subject: [PATCH 05/10] Change schema order in the docs: move option to the top, move visual down. PiperOrigin-RevId: 627036617 Change-Id: Icb18a4afab7d549baee8ed0df89e98dfac4d6e6c --- doc/XMLreference.rst | 1752 +++++++++++++++++++++--------------------- doc/XMLschema.rst | 226 +++--- 2 files changed, 992 insertions(+), 986 deletions(-) diff --git a/doc/XMLreference.rst b/doc/XMLreference.rst index 44230bb8..78703cd7 100644 --- a/doc/XMLreference.rst +++ b/doc/XMLreference.rst @@ -182,6 +182,7 @@ how to use includes and how to modularize large files if desired. file is not in the same directory, it should be prefixed with a relative path. + .. _mujoco: **mujoco** (!) @@ -195,6 +196,363 @@ The unique top-level element, identifying the XML file as an MJCF model file. The name of the model. This name is shown in the title bar of :ref:`simulate.cc `. + +.. _option: + +**option** (*) +~~~~~~~~~~~~~~ + +This element is in one-to-one correspondence with the low level structure mjOption contained in the field mjModel.opt of +mjModel. These are simulation options and do not affect the compilation process in any way; they are simply copied into +the low level model. Even though mjOption can be modified by the user at runtime, it is nevertheless a good idea to +adjust it properly through the XML. + +.. _option-timestep: + +:at:`timestep`: :at-val:`real, "0.002"` + Simulation time step in seconds. This is the single most important parameter affecting the speed-accuracy trade-off + which is inherent in every physics simulation. Smaller values result in better accuracy and stability. To achieve + real-time performance, the time step must be larger than the CPU time per step (or 4 times larger when using the RK4 + integrator). The CPU time is measured with internal timers. It should be monitored when adjusting the time step. + MuJoCo can simulate most robotic systems a lot faster than real-time, however models with many floating objects + (resulting in many contacts) are more demanding computationally. Keep in mind that stability is determined not only + by the time step but also by the :ref:`CSolver`; in particular softer constraints can be simulated with larger time + steps. When fine-tuning a challenging model, it is recommended to experiment with both settings jointly. In + optimization-related applications, real-time is no longer good enough and instead it is desirable to run the + simulation as fast as possible. In that case the time step should be made as large as possible. + +.. _option-apirate: + +:at:`apirate`: :at-val:`real, "100"` + This parameter determines the rate (in Hz) at which an external API allows the update function to be executed. This + mechanism is used to simulate devices with limited communication bandwidth. It only affects the socket API and not + the physics simulation. + +.. _option-impratio: + +:at:`impratio`: :at-val:`real, "1"` + This attribute determines the ratio of frictional-to-normal constraint impedance for elliptic friction cones. The + setting of solimp determines a single impedance value for all contact dimensions, which is then modulated by this + attribute. Settings larger than 1 cause friction forces to be "harder" than normal forces, having the general effect + of preventing slip, without increasing the actual friction coefficient. For pyramidal friction cones the situation is + more complex because the pyramidal approximation mixes normal and frictional dimensions within each basis vector; but + the overall effect of this attribute is qualitatively similar. + +.. _option-gravity: + +:at:`gravity`: :at-val:`real(3), "0 0 -9.81"` + Gravitational acceleration vector. In the default world orientation the Z-axis points up. The MuJoCo GUI is organized + around this convention (both the camera and perturbation commands are based on it) so we do not recommend deviating + from it. + +.. _option-wind: + +:at:`wind`: :at-val:`real(3), "0 0 0"` + Velocity vector of the medium (i.e., wind). This vector is subtracted from the 3D translational velocity of each + body, and the result is used to compute viscous, lift and drag forces acting on the body; recall :ref:`Passive forces + ` in the Computation chapter. The magnitude of these forces scales with the values of the next two + attributes. + + +.. _option-magnetic: + +:at:`magnetic`: :at-val:`real(3), "0 -0.5 0"` + Global magnetic flux. This vector is used by magnetometer sensors, which are defined as sites and return the magnetic + flux at the site position expressed in the site frame. + +.. _option-density: + +:at:`density`: :at-val:`real, "0"` + Density of the medium, not to be confused with the geom density used to infer masses and inertias. This parameter is + used to simulate lift and drag forces, which scale quadratically with velocity. In SI units the density of air is + around 1.2 while the density of water is around 1000 depending on temperature. Setting density to 0 disables lift and + drag forces. + +.. _option-viscosity: + +:at:`viscosity`: :at-val:`real, "0"` + Viscosity of the medium. This parameter is used to simulate viscous forces, which scale linearly with velocity. In SI + units the viscosity of air is around 0.00002 while the viscosity of water is around 0.0009 depending on temperature. + Setting viscosity to 0 disables viscous forces. Note that the default Euler :ref:`integrator ` handles + damping in the joints implicitly – which improves stability and accuracy. It does not presently do this with body + viscosity. Therefore, if the goal is merely to create a damped simulation (as opposed to modeling the specific + effects of viscosity), we recommend using joint damping rather than body viscosity, or switching to the + :at:`implicit` or :at:`implicitfast` integrators. + +.. _option-o_margin: + +:at:`o_margin`: :at-val:`real, "0"` + This attribute replaces the margin parameter of all active contact pairs when :ref:`Contact override ` is + enabled. Otherwise MuJoCo uses the element-specific margin attribute of :ref:`geom` or + :ref:`pair` depending on how the contact pair was generated. See also :ref:`Collision` in the + Computation chapter. The related gap parameter does not have a global override. + +.. _option-o_solref: +.. _option-o_solimp: +.. _option-o_friction: + +:at:`o_solref`, :at:`o_solimp`, :at:`o_friction` + These attributes replace the solref, solimp and friction parameters of all active contact pairs when contact override is + enabled. See :ref:`CSolver` for details. + +.. _option-integrator: + +:at:`integrator`: :at-val:`[Euler, RK4, implicit, implicitfast], "Euler"` + This attribute selects the numerical :ref:`integrator ` to be used. Currently the available + integrators are the semi-implicit Euler method, the fixed-step 4-th order Runge Kutta method, the + Implicit-in-velocity Euler method, and :at:`implicitfast`, which drops the Coriolis and centrifugal terms. See + :ref:`Numerical Integration` for more details. + +.. _option-cone: + +:at:`cone`: :at-val:`[pyramidal, elliptic], "pyramidal"` + The type of contact friction cone. Elliptic cones are a better model of the physical reality, but pyramidal cones + sometimes make the solver faster and more robust. + +.. _option-jacobian: + +:at:`jacobian`: :at-val:`[dense, sparse, auto], "auto"` + The type of constraint Jacobian and matrices computed from it. Auto resolves to dense when the number of degrees of + freedom is up to 60, and sparse over 60. + +.. _option-solver: + +:at:`solver`: :at-val:`[PGS, CG, Newton], "Newton"` + This attribute selects one of the constraint solver :ref:`algorithms ` described in the Computation + chapter. Guidelines for solver selection and parameter tuning are available in the :ref:`Algorithms ` + section above. + +.. _option-iterations: + +:at:`iterations`: :at-val:`int, "100"` + Maximum number of iterations of the constraint solver. When the warmstart attribute of :ref:`flag ` is + enabled (which is the default), accurate results are obtained with fewer iterations. Larger and more complex systems + with many interacting constraints require more iterations. Note that mjData.solver contains statistics about solver + convergence, also shown in the profiler. + +.. _option-tolerance: + +:at:`tolerance`: :at-val:`real, "1e-8"` + Tolerance threshold used for early termination of the iterative solver. For PGS, the threshold is applied to the cost + improvement between two iterations. For CG and Newton, it is applied to the smaller of the cost improvement and the + gradient norm. Set the tolerance to 0 to disable early termination. + +.. _option-ls_iterations: + +:at:`ls_iterations`: :at-val:`int, "50"` + Maximum number of linesearch iterations performed by CG/Newton constraint solvers. Ensures that at most + :ref:`iterations` times :ref:`ls_iterations` linesearch iterations are + performed during each constraint solve. + +.. _option-ls_tolerance: + +:at:`ls_tolerance`: :at-val:`real, "0.01"` + Tolerance threshold used for early termination of the linesearch algorithm. + +.. _option-noslip_iterations: + +:at:`noslip_iterations`: :at-val:`int, "0"` + Maximum number of iterations of the Noslip solver. This is a post-processing step executed after the main solver. It + uses a modified PGS method to suppress slip/drift in friction dimensions resulting from the soft-constraint model. + The default setting 0 disables this post-processing step. + +.. _option-noslip_tolerance: + +:at:`noslip_tolerance`: :at-val:`real, "1e-6"` + Tolerance threshold used for early termination of the Noslip solver. + +.. _option-mpr_iterations: + +:at:`mpr_iterations`: :at-val:`int, "50"` + Maximum number of iterations of the MPR algorithm used for convex mesh collisions. This rarely needs to be adjusted, + except in situations where some geoms have very large aspect ratios. + +.. _option-mpr_tolerance: + +:at:`mpr_tolerance`: :at-val:`real, "1e-6"` + Tolerance threshold used for early termination of the MPR algorithm. + +.. _option-sdf_iterations: + +:at:`sdf_iterations`: :at-val:`int, "10"` + Number of iterations used for Signed Distance Field collisions (per initial point). + +.. _option-sdf_initpoints: + +:at:`sdf_initpoints`: :at-val:`int, "40"` + Number of starting points used for finding contacts with Signed Distance Field collisions. + +.. youtube:: H9qG9Zf2W44 + :align: right + :width: 240px + +.. _option-actuatorgroupdisable: + +:at:`actuatorgroupdisable`: :at-val:`int(31), optional` + List of actuator groups to disable. Actuators whose :ref:`group` is in this list will produce + no force. If they are stateful, their activation states will not be integrated. Internally this list is + implemented as an integer bitfield, so values must be in the range ``0 <= group <= 30``. If not set, all actuator + groups are enabled. See `example model + `__ + and associated screen-capture on the right. + +.. _option-flag: + +:el-prefix:`option/` |-| **flag** (?) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This element sets the flags that enable and disable different parts of the simulation pipeline. The actual flags used at +runtime are represented as the bits of two integers, namely mjModel.opt.disableflags and mjModel.opt.enableflags, used +to disable standard features and enable optional features respectively. The reason for this separation is that setting +both integers to 0 restores the default. In the XML we do not make this separation explicit, except for the default +attribute values - which are "enable" for flags corresponding to standard features, and "disable" for flags +corresponding to optional features. In the documentation below, we explain what happens when the setting is different +from its default. + +.. _option-flag-constraint: + +:at:`constraint`: :at-val:`[disable, enable], "enable"` + This flag disables all standard computations related to the constraint solver. As a result, no constraint forces are + applied. Note that the next four flags disable the computations related to a specific type of constraint. Both this + flag and the type-specific flag must be set to "enable" for a given computation to be performed. + +.. _option-flag-equality: + +:at:`equality`: :at-val:`[disable, enable], "enable"` + This flag disables all standard computations related to equality constraints. + +.. _option-flag-frictionloss: + +:at:`frictionloss`: :at-val:`[disable, enable], "enable"` + This flag disables all standard computations related to friction loss constraints. + +.. _option-flag-limit: + +:at:`limit`: :at-val:`[disable, enable], "enable"` + This flag disables all standard computations related to joint and tendon limit constraints. + +.. _option-flag-contact: + +:at:`contact`: :at-val:`[disable, enable], "enable"` + This flag disables collision detection and all standard computations related to contact constraints. + +.. _option-flag-passive: + +:at:`passive`: :at-val:`[disable, enable], "enable"` + This flag disables the simulation of joint and tendon spring-dampers, fluid dynamics forces, and custom passive + forces computed by the :ref:`mjcb_passive` callback. As a result, no passive forces are applied. + +.. _option-flag-gravity: + +:at:`gravity`: :at-val:`[disable, enable], "enable"` + This flag causes the gravitational acceleration vector in mjOption to be replaced with (0 0 0) at runtime, without + changing the value in mjOption. Once the flag is re-enabled, the value in mjOption is used. + +.. _option-flag-clampctrl: + +:at:`clampctrl`: :at-val:`[disable, enable], "enable"` + This flag disables the clamping of control inputs to all actuators, even if the actuator-specific attributes are set + to enable clamping. + +.. _option-flag-warmstart: + +:at:`warmstart`: :at-val:`[disable, enable], "enable"` + This flag disables warm-starting of the constraint solver. By default the solver uses the solution (i.e., the + constraint force) from the previous time step to initialize the iterative optimization. This feature should be + disabled when evaluating the dynamics at a collection of states that do not form a trajectory - in which case warm + starts make no sense and are likely to slow down the solver. + +.. _option-flag-filterparent: + +:at:`filterparent`: :at-val:`[disable, enable], "enable"` + This flag disables the filtering of contact pairs where the two geoms belong to a parent and child body; recall + contact :ref:`selection ` in the Computation chapter. + +.. _option-flag-actuation: + +:at:`actuation`: :at-val:`[disable, enable], "enable"` + This flag disables all standard computations related to actuator forces, including the actuator dynamics. As a + result, no actuator forces are applied to the simulation. + +.. _option-flag-refsafe: + +:at:`refsafe`: :at-val:`[disable, enable], "enable"` + This flag enables a safety mechanism that prevents instabilities due to solref[0] being too small compared to the + simulation timestep. Recall that solref[0] is the stiffness of the virtual spring-damper used for constraint + stabilization. If this setting is enabled, the solver uses max(solref[0], 2*timestep) in place of solref[0] + separately for each active constraint. + +.. _option-flag-sensor: + +:at:`sensor`: :at-val:`[disable, enable], "enable"` + This flag disables all computations related to sensors. When disabled, sensor values will remain constant, either + zeros if disabled at the start of simulation, or, if disabled at runtime, whatever value was last computed. + +.. _option-flag-midphase: + +:at:`midphase`: :at-val:`[disable, enable], "enable"` + This flag disables the mid-phase collision filtering using a static AABB bounding volume hierarchy (a BVH binary + tree). If disabled, all geoms pairs that are allowed to collide are checked for collisions. + +.. _option-flag-eulerdamp: + +:at:`eulerdamp`: :at-val:`[disable, enable], "enable"` + This flag disables implicit integration with respect to joint damping in the Euler integrator. See the + :ref:`Numerical Integration` section for more details. + +.. _option-flag-override: + +:at:`override`: :at-val:`[disable, enable], "disable"` + This flag enables to :ref:`Contact override ` mechanism explained above. + +.. _option-flag-energy: + +:at:`energy`: :at-val:`[disable, enable], "disable"` + This flag enables the computation of kinetic and potential energy, stored in mjData.energy and displayed in the GUI. + This feature adds some CPU time but it is usually negligible. Monitoring energy for a system that is supposed to be + energy-conserving is one of the best ways to assess the accuracy of a complex simulation. + +.. _option-flag-fwdinv: + +:at:`fwdinv`: :at-val:`[disable, enable], "disable"` + This flag enables the automatic comparison of forward and inverse dynamics. When enabled, the inverse dynamics is + invoked after mj_forward (or internally within mj_step) and the difference in applied forces is recorded in + mjData.solver_fwdinv[2]. The first value is the relative norm of the discrepancy in joint space, the next is in + constraint space. + +.. _option-flag-invdiscrete: + +:at:`invdiscrete`: :at-val:`[disable, enable], "disable"` + This flag enables discrete-time inverse dynamics with :ref:`mj_inverse` for all + :ref:`integrators` other than ``RK4``. Recall from the + :ref:`numerical integration` section that the one-step integrators (``Euler``, ``implicit`` and + ``implicitfast``), modify the mass matrix :math:`M \rightarrow M-hD`. This implies that finite-differenced + accelerations :math:`(v_{t+h} - v_t)/h` will not correspond to the continuous-time acceleration ``mjData.qacc``. + When this flag is enabled, :ref:`mj_inverse` will interpret ``qacc`` as having been computed from the difference of + two sequential velocities, and undo the above modification. + + +.. _option-flag-multiccd: + +:at:`multiccd`: :at-val:`[disable, enable], "disable"` |nbsp| |nbsp| |nbsp| (experimental feature) + This flag enables multiple-contact collision detection for geom pairs that use the general-purpose convex-convex + collider based on :ref:`libccd ` e.g., mesh-mesh collisions. This can be useful when the contacting geoms + have a flat surface, and the single contact point generated by the convex-convex collider cannot accurately capture + the surface contact, leading to instabilities that typically manifest as sliding or wobbling. Multiple contact points + are found by rotating the two geoms by ±1e-3 radians around the tangential axes and re-running the collision + function. If a new contact is detected it is added, allowing for up to 4 additional contact points. This feature is + currently considered experimental, and both the behavior and the way it is activated may change in the future. + +.. _option-flag-island: + +:at:`island`: :at-val:`[disable, enable], "disable"` + This flag enables discovery of constraint islands: disjoint sets of constraints and + degrees-of-freedom that do not interact. The flag currently has no effect on the physics pipeline, but enabling it + allows for `island visualization `__. + In a future release, the constraint solver will exploit the disjoint nature of constraint islands. + + + .. _compiler: **compiler** (*) @@ -627,525 +985,6 @@ parameters. center the view of the free camera when the model is first loaded. -.. _visual: - -**visual** (*) -~~~~~~~~~~~~~~ - -This element is in one-to-one correspondence with the low level structure mjVisual contained in the field mjModel.vis -of mjModel. The settings here affect the visualizer, or more precisely the abstract phase of visualization which -yields a list of geometric entities for subsequent rendering. The settings here are global, in contrast with the -element-specific visual settings. The global and element-specific settings refer to non-overlapping properties. Some -of the global settings affect properties such as triangulation of geometric primitives that cannot be set per element. -Other global settings affect the properties of decorative objects, i.e., objects such as contact points and force -arrows which do not correspond to model elements. The visual settings are grouped semantically into several -subsections. -|br| This element is a good candidate for the :ref:`file include ` mechanism. One can create an XML file with -coordinated visual settings corresponding to a "theme", and then include this file in multiple models. - -.. _visual-global: - -:el-prefix:`visual/` |-| **global** (?) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -While all settings in mjVisual are global, the settings here could not be fit into any of the other subsections. So this -is effectively a miscellaneous subsection. - -.. _visual-global-fovy: - -:at:`fovy`: :at-val:`real, "45"` - This attribute specifies the vertical field of view of the free camera, i.e., the camera that is always available in - the visualizer even if no cameras are explicitly defined in the model. It is always expressed in degrees, regardless - of the setting of the angle attribute of :ref:`compiler `, and is also represented in the low level model - in degrees. This is because we pass it to OpenGL which uses degrees. The same convention applies to the fovy - attribute of the :ref:`camera ` element below. - -.. _visual-global-ipd: - -:at:`ipd`: :at-val:`real, "0.068"` - This attribute specifies the inter-pupilary distance of the free camera. It only affects the rendering in - stereoscopic mode. The left and right viewpoints are offset by half of this value in the corresponding direction. - -.. _visual-global-azimuth: - -:at:`azimuth`: :at-val:`real, "90"` - This attribute specifies the initial azimuth of the free camera around the vertical z-axis, in degrees. A value of 0 - corresponds to looking in the positive x direction, while the default value of 90 corresponds to looking in the - positive y direction. The look-at point itself is specified by the :ref:`statistic/center` - attribute, while the distance from the look-at point is controlled by the :ref:`statistic/extent` - attribute. - -.. _visual-global-elevation: - -:at:`elevation`: :at-val:`real, "-45"` - This attribute specifies the initial elevation of the free camera with respect to the lookat point. Note that since - this is a rotation around a vector parallel to the camera's X-axis (right in pixel space), *negative* numbers - correspond to moving the camera *up* from the horizontal plane, and vice-versa. The look-at point itself is specified - by the :ref:`statistic/center` attribute, while the distance from the look-at point is controlled - by the :ref:`statistic/extent` attribute. - -.. _visual-global-linewidth: - -:at:`linewidth`: :at-val:`real, "1"` - This attribute specifies the line-width in the sense of OpenGL. It affects the rendering in wire-frame mode. - -.. _visual-global-glow: - -:at:`glow`: :at-val:`real, "0.3"` - The value of this attribute is added to the emission coefficient of all geoms attached to the selected body. As a - result, the selected body appears to glow. - -.. _visual-global-realtime: - -:at:`realtime`: :at-val:`real, "1"` - This value sets the initial real-time factor of the model, when loaded in `simulate`. 1: real time. Less than 1: - slower than real time. Must be greater than 0. - -.. _visual-global-offwidth: - -:at:`offwidth`: :at-val:`int, "640"` - This and the next attribute specify the size in pixels of the off-screen OpenGL rendering buffer. This attribute - specifies the width of the buffer. The size of this buffer can also be adjusted at runtime, but it is usually more - convenient to set it in the XML. - -.. _visual-global-offheight: - -:at:`offheight`: :at-val:`int, "480"` - This attribute specifies the height in pixels of the OpenGL off-screen rendering buffer. - -.. _visual-global-ellipsoidinertia: - -:at:`ellipsoidinertia`: :at-val:`[false, true], "false"` - This attribute specifies how the equivalent inertia is visualized. "false": - use box, "true": use ellipsoid. - -.. _visual-global-bvactive: - -:at:`bvactive`: :at-val:`[false, true], "true"` - This attribute specifies whether collision and raycasting code should mark elements of Bounding Volume Hierarchies - as intersecting, for the purpose of visualization. Setting this attribute to "false" can speed up simulation for - models with high-resolution meshes. - -.. _visual-quality: - -:el-prefix:`visual/` |-| **quality** (?) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -This element specifies settings that affect the quality of the rendering. Larger values result in higher quality but -possibly slower speed. Note that :ref:`simulate.cc ` displays the frames per second (FPS). The target FPS is -60 Hz; if the number shown in the visualizer is substantially lower, this means that the GPU is over-loaded and the -visualization should somehow be simplified. - -.. _visual-quality-shadowsize: - -:at:`shadowsize`: :at-val:`int, "4096"` - This attribute specifies the size of the square texture used for shadow mapping. Higher values result is smoother - shadows. The size of the area over which a :ref:`light ` can cast shadows also affects smoothness, so - these settings should be adjusted jointly. The default here is somewhat conservative. Most modern GPUs are able to - handle significantly larger textures without slowing down. - -.. _visual-quality-offsamples: - -:at:`offsamples`: :at-val:`int, "4"` - This attribute specifies the number of multi-samples for offscreen rendering. Larger values produce better - anti-aliasing but can slow down the GPU. Set this to 0 to disable multi-sampling. Note that this attribute only - affects offscreen rendering. For regular window rendering, multi-sampling is specified in an OS-dependent way when - the OpenGL context for the window is first created, and cannot be changed from within MuJoCo. - |br| When rendering segmentation images, multi-sampling is automatically disabled so as not to average segmentation - indices. However, some rendering backends ignore the automatic disabling. If your segmentation images contain bad - indices, try manually setting this attribute to 0. - -.. _visual-quality-numslices: - -:at:`numslices`: :at-val:`int, "28"` - This and the next three attributes specify the density of internally-generated meshes for geometric primitives. Such - meshes are only used for rendering, while the collision detector works with the underlying analytic surfaces. This - value is passed to the various visualizer functions as the "slices" parameter as used in GLU. It specifies the number - of subdivisions around the Z-axis, similar to lines of longitude. - -.. _visual-quality-numstacks: - -:at:`numstacks`: :at-val:`int, "16"` - This value of this attribute is passed to the various visualization functions as the "stacks" parameter as used in - GLU. It specifies the number of subdivisions along the Z-axis, similar to lines of latitude. - -.. _visual-quality-numquads: - -:at:`numquads`: :at-val:`int, "4"` - This attribute specifies the number of rectangles for rendering box faces, automatically-generated planes (as opposed - to geom planes which have an element-specific attribute with the same function), and sides of height fields. Even - though a geometrically correct rendering can be obtained by setting this value to 1, illumination works better for - larger values because we use per-vertex illumination (as opposed to per-fragment). - - -.. _visual-headlight: - -:el-prefix:`visual/` |-| **headlight** (?) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -This element is used to adjust the properties of the headlight. There is always a built-in headlight, in addition to any -lights explicitly defined in the model. The headlight is a directional light centered at the current camera and pointed -in the direction in which the camera is looking. It does not cast shadows (which would be invisible anyway). Note that -lights are additive, so if explicit lights are defined in the model, the intensity of the headlight would normally need -to be reduced. - -.. _visual-headlight-ambient: - -:at:`ambient`: :at-val:`real(3), "0.1 0.1 0.1"` - The ambient component of the headlight, in the sense of OpenGL. The alpha component here and in the next two - attributes is set to 1 and cannot be adjusted. - -.. _visual-headlight-diffuse: - -:at:`diffuse`: :at-val:`real(3), "0.4 0.4 0.4"` - The diffuse component of the headlight, in the sense of OpenGL. - -.. _visual-headlight-specular: - -:at:`specular`: :at-val:`real(3), "0.5 0.5 0.5"` - The specular component of the headlight, in the sense of OpenGL. - -.. _visual-headlight-active: - -:at:`active`: :at-val:`int, "1"` - This attribute enables and disables the headlight. A value of 0 means disabled, any other value means enabled. - - -.. _visual-map: - -:el-prefix:`visual/` |-| **map** (?) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -This element is used to specify scaling quantities that affect both the visualization and built-in mouse perturbations. -Unlike the scaling quantities in the next element which are specific to spatial extent, the quantities here are -miscellaneous. - -.. _visual-map-stiffness: - -:at:`stiffness`: :at-val:`real, "100"` - This attribute controls the strength of mouse perturbations. The internal perturbation mechanism simulates a - mass-spring-damper with critical damping, unit mass, and stiffness given here. Larger values mean that a larger force - will be applied for the same displacement between the selected body and the mouse-controlled target. - -.. _visual-map-stiffnessrot: - -:at:`stiffnessrot`: :at-val:`real, "500"` - Same as above but applies to rotational perturbations rather than translational perturbations. Empirically, the - rotational stiffness needs to be larger in order for rotational mouse perturbations to have an effect. - -.. _visual-map-force: - -:at:`force`: :at-val:`real, "0.005"` - This attributes controls the visualization of both contact forces and perturbation forces. The length of the rendered - force vector equals the force magnitude multiplied by the value of this attribute and divided by the mean body mass - for the model (see :ref:`statistic ` element). - -.. _visual-map-torque: - -:at:`torque`: :at-val:`real, "0.1"` - Same as above, but controls the rendering of contact torque and perturbation torque rather than force (currently - disabled). - -.. _visual-map-alpha: - -:at:`alpha`: :at-val:`real, "0.3"` - When transparency is turned on in the visualizer, the geoms attached to all moving bodies are made more transparent. - This is done by multiplying the geom-specific alpha values by this value. - -.. _visual-map-fogstart: - -:at:`fogstart`: :at-val:`real, "3"` - The visualizer can simulate linear fog, in the sense of OpenGL. The start position of the fog is the model extent - (see :ref:`statistic ` element) multiplied by the value of this attribute. - -.. _visual-map-fogend: - -:at:`fogend`: :at-val:`real, "10"` - The end position of the fog is the model extent multiplied by the value of this attribute. - -.. _visual-map-znear: - -:at:`znear`: :at-val:`real, "0.01"` - This and the next attribute determine the clipping planes of the OpenGL projection. The near clipping plane is - particularly important: setting it too close causes (often severe) loss of resolution in the depth buffer, while - setting it too far causes objects of interest to be clipped, making it impossible to zoom in. The distance to the - near clipping plane is the model ``extent`` multiplied by the value of this attribute. Must be strictly positive. - -.. _visual-map-zfar: - -:at:`zfar`: :at-val:`real, "50"` - The distance to the far clipping plane is the model ``extent`` multiplied by the value of this attribute. - -.. _visual-map-haze: - -:at:`haze`: :at-val:`real, "0.3"` - Proportion of the distance-to-horizon that is covered by haze (when haze rendering is enabled and a skybox is - present). - -.. _visual-map-shadowclip: - -:at:`shadowclip`: :at-val:`real, "1"` - As mentioned above, shadow quality depends on the size of the shadow texture as well as the area where a given light - can cast shadows. For directional lights, the area would be infinite unless we limited it somehow. This attribute - specifies the limits, as +/- the model extent multiplied by the present value. These limits define a square in the - plane orthogonal to the light direction. If a shadow crosses the boundary of this virtual square, it will disappear - abruptly, revealing the edges of the square. - -.. _visual-map-shadowscale: - -:at:`shadowscale`: :at-val:`real, "0.6"` - This attribute plays a similar role as the previous one, but applies to spotlights rather than directional lights. - Spotlights have a cutoff angle, limited internally to 80 deg. However this angle is often too large to obtain good - quality shadows, and it is necessary to limit the shadow to a smaller cone. The angle of the cone in which shadows - can be cast is the light cutoff multiplied by the present value. - -.. _visual-map-actuatortendon: - -:at:`actuatortendon`: :at-val:`real, "2"` - Ratio of actuator width to tendon width for rendering of actuators attached to tendons. - - -.. _visual-scale: - -:el-prefix:`visual/` |-| **scale** (?) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The settings in this element control the spatial extent of various decorative objects. In all cases, the rendered size -equals the mean body size (see :ref:`statistic ` element) multiplied by the value of an attribute -documented below. - -.. _visual-scale-forcewidth: - -:at:`forcewidth`: :at-val:`real, "0.1"` - The radius of the arrows used to render contact forces and perturbation forces. - -.. _visual-scale-contactwidth: - -:at:`contactwidth`: :at-val:`real, "0.3"` - The radius of the cylinders used to render contact points. The normal direction of the cylinder is aligned with the - contact normal. Making the cylinder short and wide results in a "pancake" representation of the tangent plane. - -.. _visual-scale-contactheight: - -:at:`contactheight`: :at-val:`real, "0.1"` - The height of the cylinders used to render contact points. - -.. _visual-scale-connect: - -:at:`connect`: :at-val:`real, "0.2"` - The radius of the capsules used to connect bodies and joints, resulting in an automatically generated skeleton. - -.. _visual-scale-com: - -:at:`com`: :at-val:`real, "0.4"` - The radius of the spheres used to render the centers of mass of kinematic sub-trees. - -.. _visual-scale-camera: - -:at:`camera`: :at-val:`real, "0.3"` - The size of the decorative object used to represent model cameras in the rendering. - -.. _visual-scale-light: - -:at:`light`: :at-val:`real, "0.3"` - The size of the decorative object used to represent model lights in the rendering. - -.. _visual-scale-selectpoint: - -:at:`selectpoint`: :at-val:`real, "0.2"` - The radius of the sphere used to render the selection point (i.e., the point where the user left-double-clicked to - select a body). Note that the local and global coordinates of this point can be printed in the 3D view by activating - the corresponding rendering flags. In this way, the coordinates of points of interest can be found. - -.. _visual-scale-jointlength: - -:at:`jointlength`: :at-val:`real, "1.0"` - The length of the arrows used to render joint axes. - -.. _visual-scale-jointwidth: - -:at:`jointwidth`: :at-val:`real, "0.1"` - The radius of the arrows used to render joint axes. - -.. _visual-scale-actuatorlength: - -:at:`actuatorlength`: :at-val:`real, "0.7"` - The length of the arrows used to render actuators acting on scalar joints only. - -.. _visual-scale-actuatorwidth: - -:at:`actuatorwidth`: :at-val:`real, "0.2"` - The radius of the arrows used to render actuators acting on scalar joints only. - -.. _visual-scale-framelength: - -:at:`framelength`: :at-val:`real, "1.0"` - The length of the cylinders used to render coordinate frames. The world frame is automatically scaled relative to - this setting. - -.. _visual-scale-framewidth: - -:at:`framewidth`: :at-val:`real, "0.1"` - The radius of the cylinders used to render coordinate frames. - -.. _visual-scale-constraint: - -:at:`constraint`: :at-val:`real, "0.1"` - The radius of the capsules used to render violations in spatial constraints. - -.. _visual-scale-slidercrank: - -:at:`slidercrank`: :at-val:`real, "0.2"` - The radius of the capsules used to render slider-crank mechanisms. The second part of the mechanism is automatically - scaled relative to this setting. - -.. _visual-scale-frustum: - -:at:`frustum`: :at-val:`real, "10"` - The distance of the zfar plane from the camera pinhole for rendering the frustum. - - -.. _visual-rgba: - -:el-prefix:`visual/` |-| **rgba** (?) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The settings in this element control the color and transparency (rgba) of various decorative objects. We will call this -combined attribute "color" to simplify terminology below. All values should be in the range [0 1]. An alpha value of 0 -disables the rendering of the corresponding object. - -.. _visual-rgba-fog: - -:at:`fog`: :at-val:`real(4), "0 0 0 1"` - When fog is enabled, the color of all pixels fades towards the color specified here. The spatial extent of the fading - is controlled by the fogstart and fogend attributes of the :ref:`map ` element above. - -.. _visual-rgba-haze: - -:at:`haze`: :at-val:`real(4), "1 1 1 1"` - Haze color at the horizon, used to transition between an infinite plane and a skybox smoothly. The default creates - white haze. To create a seamless transition, make sure the skybox colors near the horizon are similar to the plane - color/texture, and set the haze color somewhere in that color gamut. - -.. _visual-rgba-force: - -:at:`force`: :at-val:`real(4), "1 0.5 0.5 1"` - Color of the arrows used to render perturbation forces. - -.. _visual-rgba-inertia: - -:at:`inertia`: :at-val:`real(4), "0.8 0.2 0.2 0.6"` - Color of the boxes used to render equivalent body inertias. This is the only rgba setting that has transparency by - default, because it is usually desirable to see the geoms inside the inertia box. - -.. _visual-rgba-joint: - -:at:`joint`: :at-val:`real(4), "0.2 0.6 0.8 1"` - Color of the arrows used to render joint axes. - -.. _visual-rgba-actuator: - -:at:`actuator`: :at-val:`real(4), "0.2 0.25 0.2 1"` - Actuator color for neutral value of the control. - -.. _visual-rgba-actuatornegative: - -:at:`actuatornegative`: :at-val:`real(4), "0.2 0.6 0.9 1"` - Actuator color for most negative value of the control. - -.. _visual-rgba-actuatorpositive: - -:at:`actuatorpositive`: :at-val:`real(4), "0.9 0.4 0.2 1"` - Actuator color for most positive value of the control. - -.. _visual-rgba-com: - -:at:`com`: :at-val:`real(4), "0.9 0.9 0.9 1"` - Color of the spheres used to render sub-tree centers of mass. - -.. _visual-rgba-camera: - -:at:`camera`: :at-val:`real(4), "0.6 0.9 0.6 1"` - Color of the decorative object used to represent model cameras in the rendering. - -.. _visual-rgba-light: - -:at:`light`: :at-val:`real(4), "0.6 0.6 0.9 1"` - Color of the decorative object used to represent model lights in the rendering. - -.. _visual-rgba-selectpoint: - -:at:`selectpoint`: :at-val:`real(4), "0.9 0.9 0.1 1"` - Color of the sphere used to render the selection point. - -.. _visual-rgba-connect: - -:at:`connect`: :at-val:`real(4), "0.2 0.2 0.8 1"` - Color of the capsules used to connect bodies and joints, resulting in an automatically generated skeleton. - -.. _visual-rgba-contactpoint: - -:at:`contactpoint`: :at-val:`real(4), "0.9 0.6 0.2 1"` - Color of the cylinders used to render contact points. - -.. _visual-rgba-contactforce: - -:at:`contactforce`: :at-val:`real(4), "0.7 0.9 0.9 1"` - Color of the arrows used to render contact forces. When splitting of contact forces into normal and tangential - components is enabled, this color is used to render the normal components. - -.. _visual-rgba-contactfriction: - -:at:`contactfriction`: :at-val:`real(4), "0.9 0.8 0.4 1"` - Color of the arrows used to render contact tangential forces, only when splitting is enabled. - -.. _visual-rgba-contacttorque: - -:at:`contacttorque`: :at-val:`real(4), "0.9 0.7 0.9 1"` - Color of the arrows used to render contact torques (currently disabled). - -.. _visual-rgba-contactgap: - -:at:`contactgap`: :at-val:`real(4), "0.5, 0.8, 0.9, 1"` - Color of contacts that fall in the contact gap (and are thereby excluded from contact force computations). - -.. _visual-rgba-rangefinder: - -:at:`rangefinder`: :at-val:`real(4), "1 1 0.1 1"` - Color of line geoms used to render rangefinder sensors. - -.. _visual-rgba-constraint: - -:at:`constraint`: :at-val:`real(4), "0.9 0 0 1"` - Color of the capsules corresponding to spatial constraint violations. - -.. _visual-rgba-slidercrank: - -:at:`slidercrank`: :at-val:`real(4), "0.5 0.3 0.8 1"` - Color of slider-crank mechanisms. - -.. _visual-rgba-crankbroken: - -:at:`crankbroken`: :at-val:`real(4), "0.9 0 0 1"` - Color used to render the crank of slide-crank mechanisms, in model configurations where the specified rod length - cannot be maintained, i.e., it is "broken". - -.. _visual-rgba-frustum: - -:at:`frustum`: :at-val:`real(4), "1 1 0 0.2"` - Color used to render the camera frustum. - -.. _visual-rgba-bv: - -:at:`bv`: :at-val:`real(4), "0 1 0 0.5"` - Color used to render bounding volumes. - -.. _visual-rgba-bvactive: - -:at:`bvactive`: :at-val:`real(4), "1 0 0 0.5"` - Color used to render active bounding volumes, if the :ref:`bvactive` flag is "true". - - .. _asset: @@ -1810,360 +1649,6 @@ properties are grouped together. definition could in fact come from a defaults class. The remaining material properties always apply. -.. _option: - -**option** (*) -~~~~~~~~~~~~~~ - -This element is in one-to-one correspondence with the low level structure mjOption contained in the field mjModel.opt of -mjModel. These are simulation options and do not affect the compilation process in any way; they are simply copied into -the low level model. Even though mjOption can be modified by the user at runtime, it is nevertheless a good idea to -adjust it properly through the XML. - -.. _option-timestep: - -:at:`timestep`: :at-val:`real, "0.002"` - Simulation time step in seconds. This is the single most important parameter affecting the speed-accuracy trade-off - which is inherent in every physics simulation. Smaller values result in better accuracy and stability. To achieve - real-time performance, the time step must be larger than the CPU time per step (or 4 times larger when using the RK4 - integrator). The CPU time is measured with internal timers. It should be monitored when adjusting the time step. - MuJoCo can simulate most robotic systems a lot faster than real-time, however models with many floating objects - (resulting in many contacts) are more demanding computationally. Keep in mind that stability is determined not only - by the time step but also by the :ref:`CSolver`; in particular softer constraints can be simulated with larger time - steps. When fine-tuning a challenging model, it is recommended to experiment with both settings jointly. In - optimization-related applications, real-time is no longer good enough and instead it is desirable to run the - simulation as fast as possible. In that case the time step should be made as large as possible. - -.. _option-apirate: - -:at:`apirate`: :at-val:`real, "100"` - This parameter determines the rate (in Hz) at which an external API allows the update function to be executed. This - mechanism is used to simulate devices with limited communication bandwidth. It only affects the socket API and not - the physics simulation. - -.. _option-impratio: - -:at:`impratio`: :at-val:`real, "1"` - This attribute determines the ratio of frictional-to-normal constraint impedance for elliptic friction cones. The - setting of solimp determines a single impedance value for all contact dimensions, which is then modulated by this - attribute. Settings larger than 1 cause friction forces to be "harder" than normal forces, having the general effect - of preventing slip, without increasing the actual friction coefficient. For pyramidal friction cones the situation is - more complex because the pyramidal approximation mixes normal and frictional dimensions within each basis vector; but - the overall effect of this attribute is qualitatively similar. - -.. _option-gravity: - -:at:`gravity`: :at-val:`real(3), "0 0 -9.81"` - Gravitational acceleration vector. In the default world orientation the Z-axis points up. The MuJoCo GUI is organized - around this convention (both the camera and perturbation commands are based on it) so we do not recommend deviating - from it. - -.. _option-wind: - -:at:`wind`: :at-val:`real(3), "0 0 0"` - Velocity vector of the medium (i.e., wind). This vector is subtracted from the 3D translational velocity of each - body, and the result is used to compute viscous, lift and drag forces acting on the body; recall :ref:`Passive forces - ` in the Computation chapter. The magnitude of these forces scales with the values of the next two - attributes. - - -.. _option-magnetic: - -:at:`magnetic`: :at-val:`real(3), "0 -0.5 0"` - Global magnetic flux. This vector is used by magnetometer sensors, which are defined as sites and return the magnetic - flux at the site position expressed in the site frame. - -.. _option-density: - -:at:`density`: :at-val:`real, "0"` - Density of the medium, not to be confused with the geom density used to infer masses and inertias. This parameter is - used to simulate lift and drag forces, which scale quadratically with velocity. In SI units the density of air is - around 1.2 while the density of water is around 1000 depending on temperature. Setting density to 0 disables lift and - drag forces. - -.. _option-viscosity: - -:at:`viscosity`: :at-val:`real, "0"` - Viscosity of the medium. This parameter is used to simulate viscous forces, which scale linearly with velocity. In SI - units the viscosity of air is around 0.00002 while the viscosity of water is around 0.0009 depending on temperature. - Setting viscosity to 0 disables viscous forces. Note that the default Euler :ref:`integrator ` handles - damping in the joints implicitly – which improves stability and accuracy. It does not presently do this with body - viscosity. Therefore, if the goal is merely to create a damped simulation (as opposed to modeling the specific - effects of viscosity), we recommend using joint damping rather than body viscosity, or switching to the - :at:`implicit` or :at:`implicitfast` integrators. - -.. _option-o_margin: - -:at:`o_margin`: :at-val:`real, "0"` - This attribute replaces the margin parameter of all active contact pairs when :ref:`Contact override ` is - enabled. Otherwise MuJoCo uses the element-specific margin attribute of :ref:`geom` or - :ref:`pair` depending on how the contact pair was generated. See also :ref:`Collision` in the - Computation chapter. The related gap parameter does not have a global override. - -.. _option-o_solref: -.. _option-o_solimp: -.. _option-o_friction: - -:at:`o_solref`, :at:`o_solimp`, :at:`o_friction` - These attributes replace the solref, solimp and friction parameters of all active contact pairs when contact override is - enabled. See :ref:`CSolver` for details. - -.. _option-integrator: - -:at:`integrator`: :at-val:`[Euler, RK4, implicit, implicitfast], "Euler"` - This attribute selects the numerical :ref:`integrator ` to be used. Currently the available - integrators are the semi-implicit Euler method, the fixed-step 4-th order Runge Kutta method, the - Implicit-in-velocity Euler method, and :at:`implicitfast`, which drops the Coriolis and centrifugal terms. See - :ref:`Numerical Integration` for more details. - -.. _option-cone: - -:at:`cone`: :at-val:`[pyramidal, elliptic], "pyramidal"` - The type of contact friction cone. Elliptic cones are a better model of the physical reality, but pyramidal cones - sometimes make the solver faster and more robust. - -.. _option-jacobian: - -:at:`jacobian`: :at-val:`[dense, sparse, auto], "auto"` - The type of constraint Jacobian and matrices computed from it. Auto resolves to dense when the number of degrees of - freedom is up to 60, and sparse over 60. - -.. _option-solver: - -:at:`solver`: :at-val:`[PGS, CG, Newton], "Newton"` - This attribute selects one of the constraint solver :ref:`algorithms ` described in the Computation - chapter. Guidelines for solver selection and parameter tuning are available in the :ref:`Algorithms ` - section above. - -.. _option-iterations: - -:at:`iterations`: :at-val:`int, "100"` - Maximum number of iterations of the constraint solver. When the warmstart attribute of :ref:`flag ` is - enabled (which is the default), accurate results are obtained with fewer iterations. Larger and more complex systems - with many interacting constraints require more iterations. Note that mjData.solver contains statistics about solver - convergence, also shown in the profiler. - -.. _option-tolerance: - -:at:`tolerance`: :at-val:`real, "1e-8"` - Tolerance threshold used for early termination of the iterative solver. For PGS, the threshold is applied to the cost - improvement between two iterations. For CG and Newton, it is applied to the smaller of the cost improvement and the - gradient norm. Set the tolerance to 0 to disable early termination. - -.. _option-ls_iterations: - -:at:`ls_iterations`: :at-val:`int, "50"` - Maximum number of linesearch iterations performed by CG/Newton constraint solvers. Ensures that at most - :ref:`iterations` times :ref:`ls_iterations` linesearch iterations are - performed during each constraint solve. - -.. _option-ls_tolerance: - -:at:`ls_tolerance`: :at-val:`real, "0.01"` - Tolerance threshold used for early termination of the linesearch algorithm. - -.. _option-noslip_iterations: - -:at:`noslip_iterations`: :at-val:`int, "0"` - Maximum number of iterations of the Noslip solver. This is a post-processing step executed after the main solver. It - uses a modified PGS method to suppress slip/drift in friction dimensions resulting from the soft-constraint model. - The default setting 0 disables this post-processing step. - -.. _option-noslip_tolerance: - -:at:`noslip_tolerance`: :at-val:`real, "1e-6"` - Tolerance threshold used for early termination of the Noslip solver. - -.. _option-mpr_iterations: - -:at:`mpr_iterations`: :at-val:`int, "50"` - Maximum number of iterations of the MPR algorithm used for convex mesh collisions. This rarely needs to be adjusted, - except in situations where some geoms have very large aspect ratios. - -.. _option-mpr_tolerance: - -:at:`mpr_tolerance`: :at-val:`real, "1e-6"` - Tolerance threshold used for early termination of the MPR algorithm. - -.. _option-sdf_iterations: - -:at:`sdf_iterations`: :at-val:`int, "10"` - Number of iterations used for Signed Distance Field collisions (per initial point). - -.. _option-sdf_initpoints: - -:at:`sdf_initpoints`: :at-val:`int, "40"` - Number of starting points used for finding contacts with Signed Distance Field collisions. - -.. youtube:: H9qG9Zf2W44 - :align: right - :width: 240px - -.. _option-actuatorgroupdisable: - -:at:`actuatorgroupdisable`: :at-val:`int(31), optional` - List of actuator groups to disable. Actuators whose :ref:`group` is in this list will produce - no force. If they are stateful, their activation states will not be integrated. Internally this list is - implemented as an integer bitfield, so values must be in the range ``0 <= group <= 30``. If not set, all actuator - groups are enabled. See `example model - `__ - and associated screen-capture on the right. - -.. _option-flag: - -:el-prefix:`option/` |-| **flag** (?) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -This element sets the flags that enable and disable different parts of the simulation pipeline. The actual flags used at -runtime are represented as the bits of two integers, namely mjModel.opt.disableflags and mjModel.opt.enableflags, used -to disable standard features and enable optional features respectively. The reason for this separation is that setting -both integers to 0 restores the default. In the XML we do not make this separation explicit, except for the default -attribute values - which are "enable" for flags corresponding to standard features, and "disable" for flags -corresponding to optional features. In the documentation below, we explain what happens when the setting is different -from its default. - -.. _option-flag-constraint: - -:at:`constraint`: :at-val:`[disable, enable], "enable"` - This flag disables all standard computations related to the constraint solver. As a result, no constraint forces are - applied. Note that the next four flags disable the computations related to a specific type of constraint. Both this - flag and the type-specific flag must be set to "enable" for a given computation to be performed. - -.. _option-flag-equality: - -:at:`equality`: :at-val:`[disable, enable], "enable"` - This flag disables all standard computations related to equality constraints. - -.. _option-flag-frictionloss: - -:at:`frictionloss`: :at-val:`[disable, enable], "enable"` - This flag disables all standard computations related to friction loss constraints. - -.. _option-flag-limit: - -:at:`limit`: :at-val:`[disable, enable], "enable"` - This flag disables all standard computations related to joint and tendon limit constraints. - -.. _option-flag-contact: - -:at:`contact`: :at-val:`[disable, enable], "enable"` - This flag disables collision detection and all standard computations related to contact constraints. - -.. _option-flag-passive: - -:at:`passive`: :at-val:`[disable, enable], "enable"` - This flag disables the simulation of joint and tendon spring-dampers, fluid dynamics forces, and custom passive - forces computed by the :ref:`mjcb_passive` callback. As a result, no passive forces are applied. - -.. _option-flag-gravity: - -:at:`gravity`: :at-val:`[disable, enable], "enable"` - This flag causes the gravitational acceleration vector in mjOption to be replaced with (0 0 0) at runtime, without - changing the value in mjOption. Once the flag is re-enabled, the value in mjOption is used. - -.. _option-flag-clampctrl: - -:at:`clampctrl`: :at-val:`[disable, enable], "enable"` - This flag disables the clamping of control inputs to all actuators, even if the actuator-specific attributes are set - to enable clamping. - -.. _option-flag-warmstart: - -:at:`warmstart`: :at-val:`[disable, enable], "enable"` - This flag disables warm-starting of the constraint solver. By default the solver uses the solution (i.e., the - constraint force) from the previous time step to initialize the iterative optimization. This feature should be - disabled when evaluating the dynamics at a collection of states that do not form a trajectory - in which case warm - starts make no sense and are likely to slow down the solver. - -.. _option-flag-filterparent: - -:at:`filterparent`: :at-val:`[disable, enable], "enable"` - This flag disables the filtering of contact pairs where the two geoms belong to a parent and child body; recall - contact :ref:`selection ` in the Computation chapter. - -.. _option-flag-actuation: - -:at:`actuation`: :at-val:`[disable, enable], "enable"` - This flag disables all standard computations related to actuator forces, including the actuator dynamics. As a - result, no actuator forces are applied to the simulation. - -.. _option-flag-refsafe: - -:at:`refsafe`: :at-val:`[disable, enable], "enable"` - This flag enables a safety mechanism that prevents instabilities due to solref[0] being too small compared to the - simulation timestep. Recall that solref[0] is the stiffness of the virtual spring-damper used for constraint - stabilization. If this setting is enabled, the solver uses max(solref[0], 2*timestep) in place of solref[0] - separately for each active constraint. - -.. _option-flag-sensor: - -:at:`sensor`: :at-val:`[disable, enable], "enable"` - This flag disables all computations related to sensors. When disabled, sensor values will remain constant, either - zeros if disabled at the start of simulation, or, if disabled at runtime, whatever value was last computed. - -.. _option-flag-midphase: - -:at:`midphase`: :at-val:`[disable, enable], "enable"` - This flag disables the mid-phase collision filtering using a static AABB bounding volume hierarchy (a BVH binary - tree). If disabled, all geoms pairs that are allowed to collide are checked for collisions. - -.. _option-flag-eulerdamp: - -:at:`eulerdamp`: :at-val:`[disable, enable], "enable"` - This flag disables implicit integration with respect to joint damping in the Euler integrator. See the - :ref:`Numerical Integration` section for more details. - -.. _option-flag-override: - -:at:`override`: :at-val:`[disable, enable], "disable"` - This flag enables to :ref:`Contact override ` mechanism explained above. - -.. _option-flag-energy: - -:at:`energy`: :at-val:`[disable, enable], "disable"` - This flag enables the computation of kinetic and potential energy, stored in mjData.energy and displayed in the GUI. - This feature adds some CPU time but it is usually negligible. Monitoring energy for a system that is supposed to be - energy-conserving is one of the best ways to assess the accuracy of a complex simulation. - -.. _option-flag-fwdinv: - -:at:`fwdinv`: :at-val:`[disable, enable], "disable"` - This flag enables the automatic comparison of forward and inverse dynamics. When enabled, the inverse dynamics is - invoked after mj_forward (or internally within mj_step) and the difference in applied forces is recorded in - mjData.solver_fwdinv[2]. The first value is the relative norm of the discrepancy in joint space, the next is in - constraint space. - -.. _option-flag-invdiscrete: - -:at:`invdiscrete`: :at-val:`[disable, enable], "disable"` - This flag enables discrete-time inverse dynamics with :ref:`mj_inverse` for all - :ref:`integrators` other than ``RK4``. Recall from the - :ref:`numerical integration` section that the one-step integrators (``Euler``, ``implicit`` and - ``implicitfast``), modify the mass matrix :math:`M \rightarrow M-hD`. This implies that finite-differenced - accelerations :math:`(v_{t+h} - v_t)/h` will not correspond to the continuous-time acceleration ``mjData.qacc``. - When this flag is enabled, :ref:`mj_inverse` will interpret ``qacc`` as having been computed from the difference of - two sequential velocities, and undo the above modification. - - -.. _option-flag-multiccd: - -:at:`multiccd`: :at-val:`[disable, enable], "disable"` |nbsp| |nbsp| |nbsp| (experimental feature) - This flag enables multiple-contact collision detection for geom pairs that use the general-purpose convex-convex - collider based on :ref:`libccd ` e.g., mesh-mesh collisions. This can be useful when the contacting geoms - have a flat surface, and the single contact point generated by the convex-convex collider cannot accurately capture - the surface contact, leading to instabilities that typically manifest as sliding or wobbling. Multiple contact points - are found by rotating the two geoms by ±1e-3 radians around the tangential axes and re-running the collision - function. If a new contact is detected it is added, allowing for up to 4 additional contact points. This feature is - currently considered experimental, and both the behavior and the way it is activated may change in the future. - -.. _option-flag-island: - -:at:`island`: :at-val:`[disable, enable], "disable"` - This flag enables discovery of constraint islands: disjoint sets of constraints and - degrees-of-freedom that do not interact. The flag currently has no effect on the physics pipeline, but enabling it - allows for `island visualization `__. - In a future release, the constraint solver will exploit the disjoint nature of constraint islands. - .. _body: **(world)body** (R) @@ -7345,6 +6830,527 @@ This element sets the data for one of the keyframes. They are set in the order i Vector of mocap body quaternions, copied into mjData.mocap_quat when the simulation state is set to this keyframe. + +.. _visual: + +**visual** (*) +~~~~~~~~~~~~~~ + +This element is in one-to-one correspondence with the low level structure mjVisual contained in the field mjModel.vis +of mjModel. The settings here affect the visualizer, or more precisely the abstract phase of visualization which +yields a list of geometric entities for subsequent rendering. The settings here are global, in contrast with the +element-specific visual settings. The global and element-specific settings refer to non-overlapping properties. Some +of the global settings affect properties such as triangulation of geometric primitives that cannot be set per element. +Other global settings affect the properties of decorative objects, i.e., objects such as contact points and force +arrows which do not correspond to model elements. The visual settings are grouped semantically into several +subsections. +|br| This element is a good candidate for the :ref:`file include ` mechanism. One can create an XML file with +coordinated visual settings corresponding to a "theme", and then include this file in multiple models. + +.. _visual-global: + +:el-prefix:`visual/` |-| **global** (?) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +While all settings in mjVisual are global, the settings here could not be fit into any of the other subsections. So this +is effectively a miscellaneous subsection. + +.. _visual-global-fovy: + +:at:`fovy`: :at-val:`real, "45"` + This attribute specifies the vertical field of view of the free camera, i.e., the camera that is always available in + the visualizer even if no cameras are explicitly defined in the model. It is always expressed in degrees, regardless + of the setting of the angle attribute of :ref:`compiler `, and is also represented in the low level model + in degrees. This is because we pass it to OpenGL which uses degrees. The same convention applies to the fovy + attribute of the :ref:`camera ` element below. + +.. _visual-global-ipd: + +:at:`ipd`: :at-val:`real, "0.068"` + This attribute specifies the inter-pupilary distance of the free camera. It only affects the rendering in + stereoscopic mode. The left and right viewpoints are offset by half of this value in the corresponding direction. + +.. _visual-global-azimuth: + +:at:`azimuth`: :at-val:`real, "90"` + This attribute specifies the initial azimuth of the free camera around the vertical z-axis, in degrees. A value of 0 + corresponds to looking in the positive x direction, while the default value of 90 corresponds to looking in the + positive y direction. The look-at point itself is specified by the :ref:`statistic/center` + attribute, while the distance from the look-at point is controlled by the :ref:`statistic/extent` + attribute. + +.. _visual-global-elevation: + +:at:`elevation`: :at-val:`real, "-45"` + This attribute specifies the initial elevation of the free camera with respect to the lookat point. Note that since + this is a rotation around a vector parallel to the camera's X-axis (right in pixel space), *negative* numbers + correspond to moving the camera *up* from the horizontal plane, and vice-versa. The look-at point itself is specified + by the :ref:`statistic/center` attribute, while the distance from the look-at point is controlled + by the :ref:`statistic/extent` attribute. + +.. _visual-global-linewidth: + +:at:`linewidth`: :at-val:`real, "1"` + This attribute specifies the line-width in the sense of OpenGL. It affects the rendering in wire-frame mode. + +.. _visual-global-glow: + +:at:`glow`: :at-val:`real, "0.3"` + The value of this attribute is added to the emission coefficient of all geoms attached to the selected body. As a + result, the selected body appears to glow. + +.. _visual-global-realtime: + +:at:`realtime`: :at-val:`real, "1"` + This value sets the initial real-time factor of the model, when loaded in `simulate`. 1: real time. Less than 1: + slower than real time. Must be greater than 0. + +.. _visual-global-offwidth: + +:at:`offwidth`: :at-val:`int, "640"` + This and the next attribute specify the size in pixels of the off-screen OpenGL rendering buffer. This attribute + specifies the width of the buffer. The size of this buffer can also be adjusted at runtime, but it is usually more + convenient to set it in the XML. + +.. _visual-global-offheight: + +:at:`offheight`: :at-val:`int, "480"` + This attribute specifies the height in pixels of the OpenGL off-screen rendering buffer. + +.. _visual-global-ellipsoidinertia: + +:at:`ellipsoidinertia`: :at-val:`[false, true], "false"` + This attribute specifies how the equivalent inertia is visualized. "false": + use box, "true": use ellipsoid. + +.. _visual-global-bvactive: + +:at:`bvactive`: :at-val:`[false, true], "true"` + This attribute specifies whether collision and raycasting code should mark elements of Bounding Volume Hierarchies + as intersecting, for the purpose of visualization. Setting this attribute to "false" can speed up simulation for + models with high-resolution meshes. + +.. _visual-quality: + +:el-prefix:`visual/` |-| **quality** (?) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This element specifies settings that affect the quality of the rendering. Larger values result in higher quality but +possibly slower speed. Note that :ref:`simulate.cc ` displays the frames per second (FPS). The target FPS is +60 Hz; if the number shown in the visualizer is substantially lower, this means that the GPU is over-loaded and the +visualization should somehow be simplified. + +.. _visual-quality-shadowsize: + +:at:`shadowsize`: :at-val:`int, "4096"` + This attribute specifies the size of the square texture used for shadow mapping. Higher values result is smoother + shadows. The size of the area over which a :ref:`light ` can cast shadows also affects smoothness, so + these settings should be adjusted jointly. The default here is somewhat conservative. Most modern GPUs are able to + handle significantly larger textures without slowing down. + +.. _visual-quality-offsamples: + +:at:`offsamples`: :at-val:`int, "4"` + This attribute specifies the number of multi-samples for offscreen rendering. Larger values produce better + anti-aliasing but can slow down the GPU. Set this to 0 to disable multi-sampling. Note that this attribute only + affects offscreen rendering. For regular window rendering, multi-sampling is specified in an OS-dependent way when + the OpenGL context for the window is first created, and cannot be changed from within MuJoCo. + |br| When rendering segmentation images, multi-sampling is automatically disabled so as not to average segmentation + indices. However, some rendering backends ignore the automatic disabling. If your segmentation images contain bad + indices, try manually setting this attribute to 0. + +.. _visual-quality-numslices: + +:at:`numslices`: :at-val:`int, "28"` + This and the next three attributes specify the density of internally-generated meshes for geometric primitives. Such + meshes are only used for rendering, while the collision detector works with the underlying analytic surfaces. This + value is passed to the various visualizer functions as the "slices" parameter as used in GLU. It specifies the number + of subdivisions around the Z-axis, similar to lines of longitude. + +.. _visual-quality-numstacks: + +:at:`numstacks`: :at-val:`int, "16"` + This value of this attribute is passed to the various visualization functions as the "stacks" parameter as used in + GLU. It specifies the number of subdivisions along the Z-axis, similar to lines of latitude. + +.. _visual-quality-numquads: + +:at:`numquads`: :at-val:`int, "4"` + This attribute specifies the number of rectangles for rendering box faces, automatically-generated planes (as opposed + to geom planes which have an element-specific attribute with the same function), and sides of height fields. Even + though a geometrically correct rendering can be obtained by setting this value to 1, illumination works better for + larger values because we use per-vertex illumination (as opposed to per-fragment). + + +.. _visual-headlight: + +:el-prefix:`visual/` |-| **headlight** (?) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This element is used to adjust the properties of the headlight. There is always a built-in headlight, in addition to any +lights explicitly defined in the model. The headlight is a directional light centered at the current camera and pointed +in the direction in which the camera is looking. It does not cast shadows (which would be invisible anyway). Note that +lights are additive, so if explicit lights are defined in the model, the intensity of the headlight would normally need +to be reduced. + +.. _visual-headlight-ambient: + +:at:`ambient`: :at-val:`real(3), "0.1 0.1 0.1"` + The ambient component of the headlight, in the sense of OpenGL. The alpha component here and in the next two + attributes is set to 1 and cannot be adjusted. + +.. _visual-headlight-diffuse: + +:at:`diffuse`: :at-val:`real(3), "0.4 0.4 0.4"` + The diffuse component of the headlight, in the sense of OpenGL. + +.. _visual-headlight-specular: + +:at:`specular`: :at-val:`real(3), "0.5 0.5 0.5"` + The specular component of the headlight, in the sense of OpenGL. + +.. _visual-headlight-active: + +:at:`active`: :at-val:`int, "1"` + This attribute enables and disables the headlight. A value of 0 means disabled, any other value means enabled. + + +.. _visual-map: + +:el-prefix:`visual/` |-| **map** (?) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This element is used to specify scaling quantities that affect both the visualization and built-in mouse perturbations. +Unlike the scaling quantities in the next element which are specific to spatial extent, the quantities here are +miscellaneous. + +.. _visual-map-stiffness: + +:at:`stiffness`: :at-val:`real, "100"` + This attribute controls the strength of mouse perturbations. The internal perturbation mechanism simulates a + mass-spring-damper with critical damping, unit mass, and stiffness given here. Larger values mean that a larger force + will be applied for the same displacement between the selected body and the mouse-controlled target. + +.. _visual-map-stiffnessrot: + +:at:`stiffnessrot`: :at-val:`real, "500"` + Same as above but applies to rotational perturbations rather than translational perturbations. Empirically, the + rotational stiffness needs to be larger in order for rotational mouse perturbations to have an effect. + +.. _visual-map-force: + +:at:`force`: :at-val:`real, "0.005"` + This attributes controls the visualization of both contact forces and perturbation forces. The length of the rendered + force vector equals the force magnitude multiplied by the value of this attribute and divided by the mean body mass + for the model (see :ref:`statistic ` element). + +.. _visual-map-torque: + +:at:`torque`: :at-val:`real, "0.1"` + Same as above, but controls the rendering of contact torque and perturbation torque rather than force (currently + disabled). + +.. _visual-map-alpha: + +:at:`alpha`: :at-val:`real, "0.3"` + When transparency is turned on in the visualizer, the geoms attached to all moving bodies are made more transparent. + This is done by multiplying the geom-specific alpha values by this value. + +.. _visual-map-fogstart: + +:at:`fogstart`: :at-val:`real, "3"` + The visualizer can simulate linear fog, in the sense of OpenGL. The start position of the fog is the model extent + (see :ref:`statistic ` element) multiplied by the value of this attribute. + +.. _visual-map-fogend: + +:at:`fogend`: :at-val:`real, "10"` + The end position of the fog is the model extent multiplied by the value of this attribute. + +.. _visual-map-znear: + +:at:`znear`: :at-val:`real, "0.01"` + This and the next attribute determine the clipping planes of the OpenGL projection. The near clipping plane is + particularly important: setting it too close causes (often severe) loss of resolution in the depth buffer, while + setting it too far causes objects of interest to be clipped, making it impossible to zoom in. The distance to the + near clipping plane is the model ``extent`` multiplied by the value of this attribute. Must be strictly positive. + +.. _visual-map-zfar: + +:at:`zfar`: :at-val:`real, "50"` + The distance to the far clipping plane is the model ``extent`` multiplied by the value of this attribute. + +.. _visual-map-haze: + +:at:`haze`: :at-val:`real, "0.3"` + Proportion of the distance-to-horizon that is covered by haze (when haze rendering is enabled and a skybox is + present). + +.. _visual-map-shadowclip: + +:at:`shadowclip`: :at-val:`real, "1"` + As mentioned above, shadow quality depends on the size of the shadow texture as well as the area where a given light + can cast shadows. For directional lights, the area would be infinite unless we limited it somehow. This attribute + specifies the limits, as +/- the model extent multiplied by the present value. These limits define a square in the + plane orthogonal to the light direction. If a shadow crosses the boundary of this virtual square, it will disappear + abruptly, revealing the edges of the square. + +.. _visual-map-shadowscale: + +:at:`shadowscale`: :at-val:`real, "0.6"` + This attribute plays a similar role as the previous one, but applies to spotlights rather than directional lights. + Spotlights have a cutoff angle, limited internally to 80 deg. However this angle is often too large to obtain good + quality shadows, and it is necessary to limit the shadow to a smaller cone. The angle of the cone in which shadows + can be cast is the light cutoff multiplied by the present value. + +.. _visual-map-actuatortendon: + +:at:`actuatortendon`: :at-val:`real, "2"` + Ratio of actuator width to tendon width for rendering of actuators attached to tendons. + + +.. _visual-scale: + +:el-prefix:`visual/` |-| **scale** (?) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The settings in this element control the spatial extent of various decorative objects. In all cases, the rendered size +equals the mean body size (see :ref:`statistic ` element) multiplied by the value of an attribute +documented below. + +.. _visual-scale-forcewidth: + +:at:`forcewidth`: :at-val:`real, "0.1"` + The radius of the arrows used to render contact forces and perturbation forces. + +.. _visual-scale-contactwidth: + +:at:`contactwidth`: :at-val:`real, "0.3"` + The radius of the cylinders used to render contact points. The normal direction of the cylinder is aligned with the + contact normal. Making the cylinder short and wide results in a "pancake" representation of the tangent plane. + +.. _visual-scale-contactheight: + +:at:`contactheight`: :at-val:`real, "0.1"` + The height of the cylinders used to render contact points. + +.. _visual-scale-connect: + +:at:`connect`: :at-val:`real, "0.2"` + The radius of the capsules used to connect bodies and joints, resulting in an automatically generated skeleton. + +.. _visual-scale-com: + +:at:`com`: :at-val:`real, "0.4"` + The radius of the spheres used to render the centers of mass of kinematic sub-trees. + +.. _visual-scale-camera: + +:at:`camera`: :at-val:`real, "0.3"` + The size of the decorative object used to represent model cameras in the rendering. + +.. _visual-scale-light: + +:at:`light`: :at-val:`real, "0.3"` + The size of the decorative object used to represent model lights in the rendering. + +.. _visual-scale-selectpoint: + +:at:`selectpoint`: :at-val:`real, "0.2"` + The radius of the sphere used to render the selection point (i.e., the point where the user left-double-clicked to + select a body). Note that the local and global coordinates of this point can be printed in the 3D view by activating + the corresponding rendering flags. In this way, the coordinates of points of interest can be found. + +.. _visual-scale-jointlength: + +:at:`jointlength`: :at-val:`real, "1.0"` + The length of the arrows used to render joint axes. + +.. _visual-scale-jointwidth: + +:at:`jointwidth`: :at-val:`real, "0.1"` + The radius of the arrows used to render joint axes. + +.. _visual-scale-actuatorlength: + +:at:`actuatorlength`: :at-val:`real, "0.7"` + The length of the arrows used to render actuators acting on scalar joints only. + +.. _visual-scale-actuatorwidth: + +:at:`actuatorwidth`: :at-val:`real, "0.2"` + The radius of the arrows used to render actuators acting on scalar joints only. + +.. _visual-scale-framelength: + +:at:`framelength`: :at-val:`real, "1.0"` + The length of the cylinders used to render coordinate frames. The world frame is automatically scaled relative to + this setting. + +.. _visual-scale-framewidth: + +:at:`framewidth`: :at-val:`real, "0.1"` + The radius of the cylinders used to render coordinate frames. + +.. _visual-scale-constraint: + +:at:`constraint`: :at-val:`real, "0.1"` + The radius of the capsules used to render violations in spatial constraints. + +.. _visual-scale-slidercrank: + +:at:`slidercrank`: :at-val:`real, "0.2"` + The radius of the capsules used to render slider-crank mechanisms. The second part of the mechanism is automatically + scaled relative to this setting. + +.. _visual-scale-frustum: + +:at:`frustum`: :at-val:`real, "10"` + The distance of the zfar plane from the camera pinhole for rendering the frustum. + + +.. _visual-rgba: + +:el-prefix:`visual/` |-| **rgba** (?) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The settings in this element control the color and transparency (rgba) of various decorative objects. We will call this +combined attribute "color" to simplify terminology below. All values should be in the range [0 1]. An alpha value of 0 +disables the rendering of the corresponding object. + +.. _visual-rgba-fog: + +:at:`fog`: :at-val:`real(4), "0 0 0 1"` + When fog is enabled, the color of all pixels fades towards the color specified here. The spatial extent of the fading + is controlled by the fogstart and fogend attributes of the :ref:`map ` element above. + +.. _visual-rgba-haze: + +:at:`haze`: :at-val:`real(4), "1 1 1 1"` + Haze color at the horizon, used to transition between an infinite plane and a skybox smoothly. The default creates + white haze. To create a seamless transition, make sure the skybox colors near the horizon are similar to the plane + color/texture, and set the haze color somewhere in that color gamut. + +.. _visual-rgba-force: + +:at:`force`: :at-val:`real(4), "1 0.5 0.5 1"` + Color of the arrows used to render perturbation forces. + +.. _visual-rgba-inertia: + +:at:`inertia`: :at-val:`real(4), "0.8 0.2 0.2 0.6"` + Color of the boxes used to render equivalent body inertias. This is the only rgba setting that has transparency by + default, because it is usually desirable to see the geoms inside the inertia box. + +.. _visual-rgba-joint: + +:at:`joint`: :at-val:`real(4), "0.2 0.6 0.8 1"` + Color of the arrows used to render joint axes. + +.. _visual-rgba-actuator: + +:at:`actuator`: :at-val:`real(4), "0.2 0.25 0.2 1"` + Actuator color for neutral value of the control. + +.. _visual-rgba-actuatornegative: + +:at:`actuatornegative`: :at-val:`real(4), "0.2 0.6 0.9 1"` + Actuator color for most negative value of the control. + +.. _visual-rgba-actuatorpositive: + +:at:`actuatorpositive`: :at-val:`real(4), "0.9 0.4 0.2 1"` + Actuator color for most positive value of the control. + +.. _visual-rgba-com: + +:at:`com`: :at-val:`real(4), "0.9 0.9 0.9 1"` + Color of the spheres used to render sub-tree centers of mass. + +.. _visual-rgba-camera: + +:at:`camera`: :at-val:`real(4), "0.6 0.9 0.6 1"` + Color of the decorative object used to represent model cameras in the rendering. + +.. _visual-rgba-light: + +:at:`light`: :at-val:`real(4), "0.6 0.6 0.9 1"` + Color of the decorative object used to represent model lights in the rendering. + +.. _visual-rgba-selectpoint: + +:at:`selectpoint`: :at-val:`real(4), "0.9 0.9 0.1 1"` + Color of the sphere used to render the selection point. + +.. _visual-rgba-connect: + +:at:`connect`: :at-val:`real(4), "0.2 0.2 0.8 1"` + Color of the capsules used to connect bodies and joints, resulting in an automatically generated skeleton. + +.. _visual-rgba-contactpoint: + +:at:`contactpoint`: :at-val:`real(4), "0.9 0.6 0.2 1"` + Color of the cylinders used to render contact points. + +.. _visual-rgba-contactforce: + +:at:`contactforce`: :at-val:`real(4), "0.7 0.9 0.9 1"` + Color of the arrows used to render contact forces. When splitting of contact forces into normal and tangential + components is enabled, this color is used to render the normal components. + +.. _visual-rgba-contactfriction: + +:at:`contactfriction`: :at-val:`real(4), "0.9 0.8 0.4 1"` + Color of the arrows used to render contact tangential forces, only when splitting is enabled. + +.. _visual-rgba-contacttorque: + +:at:`contacttorque`: :at-val:`real(4), "0.9 0.7 0.9 1"` + Color of the arrows used to render contact torques (currently disabled). + +.. _visual-rgba-contactgap: + +:at:`contactgap`: :at-val:`real(4), "0.5, 0.8, 0.9, 1"` + Color of contacts that fall in the contact gap (and are thereby excluded from contact force computations). + +.. _visual-rgba-rangefinder: + +:at:`rangefinder`: :at-val:`real(4), "1 1 0.1 1"` + Color of line geoms used to render rangefinder sensors. + +.. _visual-rgba-constraint: + +:at:`constraint`: :at-val:`real(4), "0.9 0 0 1"` + Color of the capsules corresponding to spatial constraint violations. + +.. _visual-rgba-slidercrank: + +:at:`slidercrank`: :at-val:`real(4), "0.5 0.3 0.8 1"` + Color of slider-crank mechanisms. + +.. _visual-rgba-crankbroken: + +:at:`crankbroken`: :at-val:`real(4), "0.9 0 0 1"` + Color used to render the crank of slide-crank mechanisms, in model configurations where the specified rod length + cannot be maintained, i.e., it is "broken". + +.. _visual-rgba-frustum: + +:at:`frustum`: :at-val:`real(4), "1 1 0 0.2"` + Color used to render the camera frustum. + +.. _visual-rgba-bv: + +:at:`bv`: :at-val:`real(4), "0 1 0 0.5"` + Color used to render bounding volumes. + +.. _visual-rgba-bvactive: + +:at:`bvactive`: :at-val:`real(4), "1 0 0 0.5"` + Color used to render active bounding volumes, if the :ref:`bvactive` flag is "true". + + + .. _default: **default** (R) diff --git a/doc/XMLschema.rst b/doc/XMLschema.rst index 236ab005..cb96f80c 100644 --- a/doc/XMLschema.rst +++ b/doc/XMLschema.rst @@ -7,6 +7,42 @@ | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | mujoco |br| |L| | | .. table:: | +| :ref:`option | \* | :class: mjcf-attributes | +|