Visualize joint and tendon limits by re-coloring.

PiperOrigin-RevId: 811590674
Change-Id: I5b65f2294a4bcda3c321fb51ebf29501bd0d416d
This commit is contained in:
Yuval Tassa
2025-09-25 19:01:34 -07:00
committed by Copybara-Service
parent c3bc793331
commit fe8384b6c5
4 changed files with 53 additions and 6 deletions
+7 -3
View File
@@ -4886,7 +4886,9 @@ length X, as in the clip on the right of `this example model
:at:`rgba`: :at-val:`real(4), "0.5 0.5 0.5 1"` :at:`rgba`: :at-val:`real(4), "0.5 0.5 0.5 1"`
Color and transparency of the tendon. When this value is different from the internal default, it overrides the Color and transparency of the tendon. When this value is different from the internal default, it overrides the
corresponding material properties. corresponding material properties. If a :at:`material` is unspecified and :at:`rgba` has the default value, limited
tendons whose length exceeds the limit are recolored using the value of the :ref:`constraint impedance<soParameters>`
:math:`d` to mix the default color and :ref:`rgba/constraint<visual-rgba-constraint>`.
.. _tendon-spatial-springlength: .. _tendon-spatial-springlength:
@@ -8292,7 +8294,9 @@ disables the rendering of the corresponding object.
.. _visual-rgba-joint: .. _visual-rgba-joint:
:at:`joint`: :at-val:`real(4), "0.2 0.6 0.8 1"` :at:`joint`: :at-val:`real(4), "0.2 0.6 0.8 1"`
Color of the arrows used to render joint axes. Color of the arrows used to render joint axes. If a joint is limited and the joint value exceeds the limit, the
value of the :ref:`constraint impedance<soParameters>` :math:`d` is used to mix this color and
:ref:`rgba/constraint<visual-rgba-constraint>`.
.. _visual-rgba-actuator: .. _visual-rgba-actuator:
@@ -8368,7 +8372,7 @@ disables the rendering of the corresponding object.
.. _visual-rgba-constraint: .. _visual-rgba-constraint:
:at:`constraint`: :at-val:`real(4), "0.9 0 0 1"` :at:`constraint`: :at-val:`real(4), "0.9 0 0 1"`
Color of the capsules corresponding to spatial constraint violations. Color corresponding to spatial constraint violations -- equality constraints, joint limits, and tendon limits.
.. _visual-rgba-slidercrank: .. _visual-rgba-slidercrank:
+6
View File
@@ -19,6 +19,12 @@ General
**Migration:** Replace ``meshdir`` and ``texturedir`` with ``compiler.meshdir`` and ``compiler.texturedir``. **Migration:** Replace ``meshdir`` and ``texturedir`` with ``compiler.meshdir`` and ``compiler.texturedir``.
- Joint decorators and spatial tendons which have limits defined and whose current value (angle or length) exceeds the
limit, are recolored by using the :ref:`constraint impedance<soParameters>` :math:`d` to mix the existing color with
:ref:`visual/rgba/constraint<visual-rgba-constraint>`. For spatial tendons, this visualization aid is active only if
no :ref:`material<tendon-spatial-material>` is set and :ref:`rgba<tendon-spatial-rgba>` is default.
Version 3.3.6 (September 15, 2025) Version 3.3.6 (September 15, 2025)
---------------------------------- ----------------------------------
+39 -2
View File
@@ -1462,7 +1462,24 @@ void mjv_addGeoms(const mjModel* m, mjData* d, const mjvOption* vopt,
mjERROR("unknown joint type %d", m->jnt_type[i]); mjERROR("unknown joint type %d", m->jnt_type[i]);
} }
f2f(thisgeom->rgba, m->vis.rgba.joint, 4); // loop over limit constraints, get impedance if this joint is limited
mjtNum imp = 0;
int efc_start = d->ne + d->nf;
int efc_end = efc_start + d->nl;
for (int k=efc_start; k < efc_end; k++) {
if (d->efc_type[k] == mjCNSTR_LIMIT_JOINT && d->efc_id[k] == i) {
imp = d->efc_KBIP[4*k + 2];
}
}
// use impedance to mix joint and constraint colors
float rgba[4];
rgba[0] = (1-imp) * m->vis.rgba.joint[0] + imp * m->vis.rgba.constraint[0];
rgba[1] = (1-imp) * m->vis.rgba.joint[1] + imp * m->vis.rgba.constraint[1];
rgba[2] = (1-imp) * m->vis.rgba.joint[2] + imp * m->vis.rgba.constraint[2];
rgba[3] = 1;
f2f(thisgeom->rgba, rgba, 4);
// vopt->label // vopt->label
if (vopt->label == mjLABEL_JOINT) { if (vopt->label == mjLABEL_JOINT) {
@@ -2290,8 +2307,28 @@ void mjv_addGeoms(const mjModel* m, mjData* d, const mjvOption* vopt,
mjv_connector(thisgeom, mjGEOM_CAPSULE, sz[0], d->wrap_xpos+3*j, d->wrap_xpos+3*j+3); mjv_connector(thisgeom, mjGEOM_CAPSULE, sz[0], d->wrap_xpos+3*j, d->wrap_xpos+3*j+3);
// set material properties // set material properties
float* rgba = m->tendon_rgba+4*i;
int tendon_matid = m->tendon_matid[i]; int tendon_matid = m->tendon_matid[i];
float rgba[4];
f2f(rgba, m->tendon_rgba+4*i, 4);
// if tendon has no material and the color is the default gray, re-color it using limit impedance
if (tendon_matid == -1 && rgba[0] == 0.5 && rgba[1] == 0.5 && rgba[2] == 0.5 && rgba[3] == 1) {
// loop over limit constraints, get impedance if this tendon is limited
mjtNum imp = 0;
int efc_start = d->ne + d->nf;
int efc_end = efc_start + d->nl;
for (int k=efc_start; k < efc_end; k++) {
if (d->efc_type[k] == mjCNSTR_LIMIT_TENDON && d->efc_id[k] == i) {
imp = d->efc_KBIP[4*k + 2];
}
}
// use impedance to mix tendon and constraint colors
rgba[0] = (1-imp) * rgba[0] + imp * m->vis.rgba.constraint[0];
rgba[1] = (1-imp) * rgba[1] + imp * m->vis.rgba.constraint[1];
rgba[2] = (1-imp) * rgba[2] + imp * m->vis.rgba.constraint[2];
}
setMaterial(m, thisgeom, tendon_matid, rgba, vopt->flags); setMaterial(m, thisgeom, tendon_matid, rgba, vopt->flags);
// override if visualizing islands // override if visualizing islands
+1 -1
View File
@@ -22,7 +22,7 @@
</worldbody> </worldbody>
<tendon> <tendon>
<spatial limited="true" range="0 .5" rgba="0 .1 1 1" width=".005"> <spatial limited="true" range="0 .5" width=".005">
<site site="hook"/> <site site="hook"/>
<site site="corner"/> <site site="corner"/>
</spatial> </spatial>