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:
Nimrod Gileadi
2022-09-06 06:11:17 -07:00
committed by Copybara-Service
parent 0784a46f62
commit a693a2d981
15 changed files with 205 additions and 36 deletions
+2
View File
@@ -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;
+1
View File
@@ -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
+28 -5
View File
@@ -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
+5 -2
View File
@@ -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);
+3
View File
@@ -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");
}