Remove `mjWARN_VGEOMFULL, handle visual geom buffer full warnings in mjvScene`.
PiperOrigin-RevId: 896483023 Change-Id: I6dde2c20d8e8e229cf95e1f002dd10525d3376e6
This commit is contained in:
committed by
Copybara-Service
parent
5a2cc6cee3
commit
0e04436d51
@@ -44,6 +44,8 @@ General
|
||||
- The ``vertcollide`` field in :ref:`mjsFlex` has been removed. It is no longer required since
|
||||
:doc:`MuJoCo Warp <mjwarp/index>` supports native flex collisions.
|
||||
|
||||
- The :ref:`mjtWarning` enum value ``mjWARN_VGEOMFULL`` is removed. Exhaustion of visual geoms is now handled
|
||||
internally by the :ref:`mjvScene`.
|
||||
|
||||
Bug fixes
|
||||
^^^^^^^^^
|
||||
|
||||
@@ -63,7 +63,6 @@ typedef enum mjtWarning_ { // warning types
|
||||
mjWARN_INERTIA = 0, // (near) singular inertia matrix
|
||||
mjWARN_CONTACTFULL, // too many contacts in contact list
|
||||
mjWARN_CNSTRFULL, // too many constraints
|
||||
mjWARN_VGEOMFULL, // too many visual geoms
|
||||
mjWARN_BADQPOS, // bad number in qpos
|
||||
mjWARN_BADQVEL, // bad number in qvel
|
||||
mjWARN_BADQACC, // bad number in qacc
|
||||
@@ -3096,7 +3095,9 @@ struct mjvScene_ { // abstract scene passed to OpenGL renderer
|
||||
// framing
|
||||
int framewidth; // frame pixel width; 0: disable framing
|
||||
float framergb[3]; // frame color
|
||||
int status; // status; 0: ok, 1: geoms exhausted
|
||||
|
||||
// geom buffer status
|
||||
int status; // 0: ok, 1: geoms exhausted, warning issued
|
||||
};
|
||||
typedef struct mjvScene_ mjvScene;
|
||||
struct mjvFigure_ { // abstract 2D figure passed to OpenGL renderer
|
||||
|
||||
@@ -77,7 +77,6 @@ typedef enum mjtWarning_ { // warning types
|
||||
mjWARN_INERTIA = 0, // (near) singular inertia matrix
|
||||
mjWARN_CONTACTFULL, // too many contacts in contact list
|
||||
mjWARN_CNSTRFULL, // too many constraints
|
||||
mjWARN_VGEOMFULL, // too many visual geoms
|
||||
mjWARN_BADQPOS, // bad number in qpos
|
||||
mjWARN_BADQVEL, // bad number in qvel
|
||||
mjWARN_BADQACC, // bad number in qacc
|
||||
|
||||
@@ -355,7 +355,9 @@ struct mjvScene_ { // abstract scene passed to OpenGL renderer
|
||||
// framing
|
||||
int framewidth; // frame pixel width; 0: disable framing
|
||||
float framergb[3]; // frame color
|
||||
int status; // status; 0: ok, 1: geoms exhausted
|
||||
|
||||
// geom buffer status
|
||||
int status; // 0: ok, 1: geoms exhausted, warning issued
|
||||
};
|
||||
typedef struct mjvScene_ mjvScene;
|
||||
|
||||
|
||||
+5
-1
@@ -91,7 +91,11 @@ void SdfVisualizer::Visualize(const mjModel* m, const mjData* d,
|
||||
for (int k = 0; k < 2; k++) {
|
||||
for (int j = 0; j < (k == 0 ? 2 : n-1); j++) {
|
||||
if (scn->ngeom >= scn->maxgeom) {
|
||||
mj_warning((mjData*)d, mjWARN_VGEOMFULL, scn->maxgeom);
|
||||
if (!scn->status) {
|
||||
mju_warning("Pre-allocated visual geom buffer is full. "
|
||||
"Increase maxgeom above %d.", scn->maxgeom);
|
||||
scn->status = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
mjvGeom* thisgeom = scn->geoms + scn->ngeom;
|
||||
|
||||
@@ -427,7 +427,11 @@ void TouchGrid::Visualize(const mjModel* m, mjData* d, const mjvOption* opt,
|
||||
continue;
|
||||
}
|
||||
if (scn->ngeom >= scn->maxgeom) {
|
||||
mj_warning(d, mjWARN_VGEOMFULL, scn->maxgeom);
|
||||
if (!scn->status) {
|
||||
mju_warning("Pre-allocated visual geom buffer is full. "
|
||||
"Increase maxgeom above %d.", scn->maxgeom);
|
||||
scn->status = 1;
|
||||
}
|
||||
mj_freeStack(d);
|
||||
return;
|
||||
} else {
|
||||
|
||||
@@ -578,12 +578,11 @@ ENUMS: Mapping[str, EnumDecl] = dict([
|
||||
('mjWARN_INERTIA', 0),
|
||||
('mjWARN_CONTACTFULL', 1),
|
||||
('mjWARN_CNSTRFULL', 2),
|
||||
('mjWARN_VGEOMFULL', 3),
|
||||
('mjWARN_BADQPOS', 4),
|
||||
('mjWARN_BADQVEL', 5),
|
||||
('mjWARN_BADQACC', 6),
|
||||
('mjWARN_BADCTRL', 7),
|
||||
('mjNWARNING', 8),
|
||||
('mjWARN_BADQPOS', 3),
|
||||
('mjWARN_BADQVEL', 4),
|
||||
('mjWARN_BADQACC', 5),
|
||||
('mjWARN_BADCTRL', 6),
|
||||
('mjNWARNING', 7),
|
||||
]),
|
||||
)),
|
||||
('mjtTimer',
|
||||
|
||||
@@ -5416,7 +5416,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
||||
name='warning',
|
||||
type=ArrayType(
|
||||
inner_type=ValueType(name='mjWarningStat'),
|
||||
extents=(8,),
|
||||
extents=(7,),
|
||||
),
|
||||
doc='warning statistics (mutable)',
|
||||
),
|
||||
@@ -10524,7 +10524,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
||||
StructFieldDecl(
|
||||
name='status',
|
||||
type=ValueType(name='int'),
|
||||
doc='status; 0: ok, 1: geoms exhausted',
|
||||
doc='0: ok, 1: geoms exhausted, warning issued',
|
||||
),
|
||||
),
|
||||
)),
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
# ==============================================================================
|
||||
"""Tests for structs.py."""
|
||||
|
||||
import re
|
||||
|
||||
from absl.testing import absltest
|
||||
|
||||
from . import ast_nodes
|
||||
@@ -36,7 +34,7 @@ class StructsTest(absltest.TestCase):
|
||||
field_names.add(field.name)
|
||||
if field.name == 'warning':
|
||||
self.assertEqual(field.type,
|
||||
type_parsing.parse_type('mjWarningStat[8]'))
|
||||
type_parsing.parse_type('mjWarningStat[7]'))
|
||||
self.assertEqual(field.doc, 'warning statistics (mutable)')
|
||||
elif field.name == 'qpos':
|
||||
self.assertEqual(field.type, type_parsing.parse_type('mjtNum*'))
|
||||
|
||||
@@ -2142,11 +2142,7 @@ void Simulate::Sync(bool state_only) {
|
||||
m_->stat = m_passive_->stat;
|
||||
}
|
||||
|
||||
// synchronize number of mjWARN_VGEOMFULL warnings
|
||||
if (d_passive_->warning[mjWARN_VGEOMFULL].number > warn_vgeomfull_prev_) {
|
||||
d_->warning[mjWARN_VGEOMFULL].number +=
|
||||
d_passive_->warning[mjWARN_VGEOMFULL].number - warn_vgeomfull_prev_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (pending_.save_xml) {
|
||||
@@ -2334,7 +2330,7 @@ void Simulate::Sync(bool state_only) {
|
||||
mjopt_prev_ = m_passive_->opt;
|
||||
mjvis_prev_ = m_passive_->vis;
|
||||
mjstat_prev_ = m_passive_->stat;
|
||||
warn_vgeomfull_prev_ = d_passive_->warning[mjWARN_VGEOMFULL].number;
|
||||
|
||||
}
|
||||
|
||||
// update settings
|
||||
@@ -2550,7 +2546,7 @@ void Simulate::LoadOnRenderThread() {
|
||||
mjopt_prev_ = m_->opt;
|
||||
opt_prev_ = opt;
|
||||
cam_prev_ = cam;
|
||||
warn_vgeomfull_prev_ = d_->warning[mjWARN_VGEOMFULL].number;
|
||||
|
||||
|
||||
// full copy on init
|
||||
m_passive_ = mj_copyModel(nullptr, m_);
|
||||
@@ -3022,7 +3018,11 @@ void Simulate::RenderLoop() {
|
||||
int nusergeom = user_scn_geoms_.size();
|
||||
int ngeom = std::min(nusergeom, this->scn.maxgeom - this->scn.ngeom);
|
||||
if (ngeom < nusergeom) {
|
||||
mj_warning(d_passive_, mjWARN_VGEOMFULL, this->scn.maxgeom);
|
||||
if (!this->scn.status) {
|
||||
mju_warning("Pre-allocated visual geom buffer is full. "
|
||||
"Increase maxgeom above %d.", this->scn.maxgeom);
|
||||
this->scn.status = 1;
|
||||
}
|
||||
}
|
||||
std::memcpy(this->scn.geoms + this->scn.ngeom, user_scn_geoms_.data(),
|
||||
ngeom * sizeof(mjvGeom));
|
||||
|
||||
@@ -147,8 +147,6 @@ class Simulate {
|
||||
mjvOption opt_prev_;
|
||||
mjvCamera cam_prev_;
|
||||
|
||||
int warn_vgeomfull_prev_;
|
||||
|
||||
// pending GUI-driven actions, to be applied at the next call to Sync
|
||||
struct {
|
||||
std::optional<std::string> save_xml;
|
||||
|
||||
@@ -1595,10 +1595,6 @@ const char* mju_warningText(int warning, size_t info) {
|
||||
"Increase arena memory allocation above %s bytes.", mju_writeNumBytes(info));
|
||||
break;
|
||||
|
||||
case mjWARN_VGEOMFULL:
|
||||
mjSNPRINTF(str, "Pre-allocated visual geom buffer is full. Increase maxgeom above %zu.", info);
|
||||
break;
|
||||
|
||||
case mjWARN_BADQPOS:
|
||||
mjSNPRINTF(str, "Nan, Inf or huge value in QPOS at DOF %zu. The simulation is unstable.", info);
|
||||
break;
|
||||
|
||||
@@ -169,7 +169,11 @@ static int bodycategory(const mjModel* m, int bodyid) {
|
||||
mjvGeom* acquireGeom(mjvScene* scn, int objid, int category, int objtype) {
|
||||
// check for overflow, SHOULD NOT OCCUR
|
||||
if (scn->ngeom >= scn->maxgeom) {
|
||||
scn->status = 1;
|
||||
if (!scn->status) {
|
||||
mju_warning("Pre-allocated visual geom buffer is full. "
|
||||
"Increase maxgeom above %d.", scn->maxgeom);
|
||||
scn->status = 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3379,7 +3383,6 @@ void mjv_updateScene(const mjModel* m, mjData* d, const mjvOption* opt,
|
||||
const mjvPerturb* pert, mjvCamera* cam, int catmask, mjvScene* scn) {
|
||||
// clear geoms
|
||||
scn->ngeom = 0;
|
||||
scn->status = 0;
|
||||
|
||||
// trigger plugin visualization hooks
|
||||
if (m->nplugin) {
|
||||
@@ -3416,10 +3419,6 @@ void mjv_updateScene(const mjModel* m, mjData* d, const mjvOption* opt,
|
||||
if (opt->flags[mjVIS_SKIN]) {
|
||||
mjv_updateActiveSkin(m, d, scn, opt);
|
||||
}
|
||||
|
||||
if (scn->status) {
|
||||
mj_warning(d, mjWARN_VGEOMFULL, scn->maxgeom);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -101,7 +101,6 @@ TEST_F(MjvSceneTest, UpdateSceneGeomsExhausted) {
|
||||
mjv_updateScene(model, data, &opt_, &pert_, &cam_, mjCAT_ALL, &scn_);
|
||||
EXPECT_EQ(scn_.status, 1);
|
||||
EXPECT_EQ(scn_.ngeom, maxgeoms);
|
||||
EXPECT_EQ(data->warning[mjWARN_VGEOMFULL].number, 1);
|
||||
|
||||
mj_deleteData(data);
|
||||
FreeSceneObjects();
|
||||
|
||||
@@ -489,12 +489,11 @@ public enum mjtWarning : int{
|
||||
mjWARN_INERTIA = 0,
|
||||
mjWARN_CONTACTFULL = 1,
|
||||
mjWARN_CNSTRFULL = 2,
|
||||
mjWARN_VGEOMFULL = 3,
|
||||
mjWARN_BADQPOS = 4,
|
||||
mjWARN_BADQVEL = 5,
|
||||
mjWARN_BADQACC = 6,
|
||||
mjWARN_BADCTRL = 7,
|
||||
mjNWARNING = 8,
|
||||
mjWARN_BADQPOS = 3,
|
||||
mjWARN_BADQVEL = 4,
|
||||
mjWARN_BADQACC = 5,
|
||||
mjWARN_BADCTRL = 6,
|
||||
mjNWARNING = 7,
|
||||
}
|
||||
public enum mjtTimer : int{
|
||||
mjTIMER_STEP = 0,
|
||||
@@ -5699,7 +5698,6 @@ public unsafe struct mjData_ {
|
||||
public mjWarningStat_ warning4;
|
||||
public mjWarningStat_ warning5;
|
||||
public mjWarningStat_ warning6;
|
||||
public mjWarningStat_ warning7;
|
||||
public mjTimerStat_ timer0;
|
||||
public mjTimerStat_ timer1;
|
||||
public mjTimerStat_ timer2;
|
||||
|
||||
@@ -359,22 +359,18 @@ public class MjScene : MonoBehaviour {
|
||||
}
|
||||
if (Data->warning3.number > 0) {
|
||||
Data->warning3.number = 0;
|
||||
throw new PhysicsRuntimeException("VGEOMFULL: who constructed a mjvScene?!");
|
||||
throw new PhysicsRuntimeException("BADQPOS: NaN/inf in qpos.");
|
||||
}
|
||||
if (Data->warning4.number > 0) {
|
||||
Data->warning4.number = 0;
|
||||
throw new PhysicsRuntimeException("BADQPOS: NaN/inf in qpos.");
|
||||
throw new PhysicsRuntimeException("BADQVEL: NaN/inf in qvel.");
|
||||
}
|
||||
if (Data->warning5.number > 0) {
|
||||
Data->warning5.number = 0;
|
||||
throw new PhysicsRuntimeException("BADQVEL: NaN/inf in qvel.");
|
||||
throw new PhysicsRuntimeException("BADQACC: NaN/inf in qacc.");
|
||||
}
|
||||
if (Data->warning6.number > 0) {
|
||||
Data->warning6.number = 0;
|
||||
throw new PhysicsRuntimeException("BADQACC: NaN/inf in qacc.");
|
||||
}
|
||||
if (Data->warning7.number > 0) {
|
||||
Data->warning7.number = 0;
|
||||
throw new PhysicsRuntimeException("BADCTRL: NaN/inf in ctrl.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11380,7 +11380,6 @@ EMSCRIPTEN_BINDINGS(mujoco_bindings) {
|
||||
.value("mjWARN_INERTIA", mjWARN_INERTIA)
|
||||
.value("mjWARN_CONTACTFULL", mjWARN_CONTACTFULL)
|
||||
.value("mjWARN_CNSTRFULL", mjWARN_CNSTRFULL)
|
||||
.value("mjWARN_VGEOMFULL", mjWARN_VGEOMFULL)
|
||||
.value("mjWARN_BADQPOS", mjWARN_BADQPOS)
|
||||
.value("mjWARN_BADQVEL", mjWARN_BADQVEL)
|
||||
.value("mjWARN_BADQACC", mjWARN_BADQACC)
|
||||
|
||||
Reference in New Issue
Block a user