Don't infer limited attributes automatically by default.
This is an amendment to 4bfc2c0311.
Add an autolimits compiler option. When true, *limited will be inferred from the presence of the *range attributes.
When false, models where limited is not specified, and range is will fail to compile.
PiperOrigin-RevId: 472438650
Change-Id: I489098e879ee695030f44e0d8cd969787e75fb90
This commit is contained in:
committed by
Copybara-Service
parent
0784a46f62
commit
a693a2d981
@@ -79,6 +79,8 @@ mjCModel::mjCModel() {
|
||||
modelfiledir.clear();
|
||||
|
||||
//------------------------ compiler settings
|
||||
// TODO(b/245077553): Toggle to true by default.
|
||||
autolimits = false;
|
||||
boundmass = 0;
|
||||
boundinertia = 0;
|
||||
settotalmass = -1;
|
||||
|
||||
@@ -107,6 +107,7 @@ class mjCModel {
|
||||
std::vector<mjCDef*> defaults; // settings for each defaults class
|
||||
|
||||
//------------------------ compiler settings
|
||||
bool autolimits; // infer "limited" attribute based on range
|
||||
double boundmass; // enfore minimum body mass
|
||||
double boundinertia; // enfore minimum body diagonal inertia
|
||||
double settotalmass; // rescale masses and inertias; <=0: ignore
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -62,6 +63,18 @@ static void checksize(double* size, mjtGeom type, mjCBase* object, const char* n
|
||||
}
|
||||
}
|
||||
|
||||
// error message for missing "limited" attribute
|
||||
static void checklimited(
|
||||
const mjCBase* obj,
|
||||
bool autolimits, const char* entity, const char* attr, int limited, bool hasrange) {
|
||||
if (!autolimits && limited == 2 && hasrange) {
|
||||
std::stringstream ss;
|
||||
ss << entity << " has `" << attr << "range` but not `" << attr << "limited`. "
|
||||
<< "set the autolimits=\"true\" compiler option, specify `" << attr << "limited` "
|
||||
<< "explicitly (\"true\" or \"false\"), or remove the `" << attr << "range` attribute.";
|
||||
throw mjCError(obj, "%s", ss.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------- class mjCError implementation ------------------------------------------
|
||||
@@ -857,7 +870,9 @@ int mjCJoint::Compile(void) {
|
||||
}
|
||||
// otherwise if limited is auto, set according to whether range is specified
|
||||
else if (limited==2) {
|
||||
limited = (range[0]==0 && range[1]==0) ? 0 : 1;
|
||||
bool hasrange = !(range[0]==0 && range[1]==0);
|
||||
checklimited(this, model->autolimits, "joint", "", limited, hasrange);
|
||||
limited = hasrange ? 1 : 0;
|
||||
}
|
||||
|
||||
// resolve limits
|
||||
@@ -3222,7 +3237,9 @@ void mjCTendon::Compile(void) {
|
||||
|
||||
// if limited is auto, set to 1 if range is specified, otherwise unlimited
|
||||
if (limited==2) {
|
||||
limited = (range[0]==0 && range[1]==0) ? 0 : 1;
|
||||
bool hasrange = !(range[0]==0 && range[1]==0);
|
||||
checklimited(this, model->autolimits, "tendon", "", limited, hasrange);
|
||||
limited = hasrange ? 1 : 0;
|
||||
}
|
||||
|
||||
// check limits
|
||||
@@ -3389,13 +3406,19 @@ void mjCActuator::Compile(void) {
|
||||
|
||||
// if limited is auto, set to 1 if range is specified, otherwise unlimited
|
||||
if (forcelimited==2) {
|
||||
forcelimited = (forcerange[0]==0 && forcerange[1]==0) ? 0 : 1;
|
||||
bool hasrange = !(forcerange[0]==0 && forcerange[1]==0);
|
||||
checklimited(this, model->autolimits, "actuator", "force", forcelimited, hasrange);
|
||||
forcelimited = hasrange ? 1 : 0;
|
||||
}
|
||||
if (ctrllimited==2) {
|
||||
ctrllimited = (ctrlrange[0]==0 && ctrlrange[1]==0) ? 0 : 1;
|
||||
bool hasrange = !(ctrlrange[0]==0 && ctrlrange[1]==0);
|
||||
checklimited(this, model->autolimits, "actuator", "ctrl", ctrllimited, hasrange);
|
||||
ctrllimited = hasrange ? 1 : 0;
|
||||
}
|
||||
if (actlimited==2) {
|
||||
actlimited = (actrange[0]==0 && actrange[1]==0) ? 0 : 1;
|
||||
bool hasrange = !(actrange[0]==0 && actrange[1]==0);
|
||||
checklimited(this, model->autolimits, "actuator", "act", actlimited, hasrange);
|
||||
actlimited = hasrange ? 1 : 0;
|
||||
}
|
||||
|
||||
// check limits
|
||||
|
||||
@@ -46,8 +46,8 @@ static const int nMJCF = 165;
|
||||
static const char* MJCF[nMJCF][mjXATTRNUM] = {
|
||||
{"mujoco", "!", "1", "model"},
|
||||
{"<"},
|
||||
{"compiler", "*", "18", "boundmass", "boundinertia", "settotalmass", "balanceinertia",
|
||||
"strippath", "coordinate", "angle", "fitaabb", "eulerseq",
|
||||
{"compiler", "*", "19", "autolimits", "boundmass", "boundinertia", "settotalmass",
|
||||
"balanceinertia", "strippath", "coordinate", "angle", "fitaabb", "eulerseq",
|
||||
"meshdir", "texturedir", "discardvisual", "convexhull", "usethread",
|
||||
"fusestatic", "inertiafromgeom", "inertiagrouprange", "exactmeshinertia"},
|
||||
{"<"},
|
||||
@@ -765,6 +765,9 @@ void mjXReader::Compiler(XMLElement* section, mjCModel* mod) {
|
||||
int n;
|
||||
|
||||
// top-level attributes
|
||||
if (MapValue(section, "autolimits", &n, bool_map, 2)) {
|
||||
mod->autolimits = (n==1);
|
||||
}
|
||||
ReadAttr(section, "boundmass", 1, &mod->boundmass, text);
|
||||
ReadAttr(section, "boundinertia", 1, &mod->boundinertia, text);
|
||||
ReadAttr(section, "settotalmass", 1, &mod->settotalmass, text);
|
||||
|
||||
@@ -696,6 +696,9 @@ void mjXWriter::Compiler(XMLElement* root) {
|
||||
if (model->exactmeshinertia) {
|
||||
WriteAttrTxt(section, "exactmeshinertia", "true");
|
||||
}
|
||||
// always enable autolimits. limited attributes will be written appropriately
|
||||
// TODO(b/245077553): Remove this when the default is true.
|
||||
WriteAttrTxt(section, "autolimits", "true");
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user