Remember compiler options during attach.

Note:
- Move compiler options into `mjsCompiler` struct.
- The compiler options from the attached model are not written by mj_SaveXML.
PiperOrigin-RevId: 689391440
Change-Id: I1d63c146a32f87c737b7a55b64a54b0ffe3aecc9
This commit is contained in:
Alessio Quaglino
2024-10-24 08:29:03 -07:00
committed by Copybara-Service
parent 1043633cc3
commit 159f23e6b4
24 changed files with 302 additions and 204 deletions
+57 -28
View File
@@ -749,6 +749,7 @@ void mjCBase::SetFrame(mjCFrame* _frame) {
mjCBody::mjCBody(mjCModel* _model) {
// set model pointer
model = _model;
if (_model) compiler = &_model->spec.compiler;
mjs_defaultBody(&spec);
elemtype = mjOBJ_BODY;
@@ -785,6 +786,8 @@ mjCBody::mjCBody(mjCModel* _model) {
mjCBody::mjCBody(const mjCBody& other, mjCModel* _model) {
model = _model;
mjSpec* origin = model->FindSpec(mjs_getString(other.model->spec.modelname));
compiler = origin ? &origin->compiler : &model->spec.compiler;
*this = other;
}
@@ -868,9 +871,11 @@ mjCBody& mjCBody::operator+=(const mjCFrame& other) {
}
// copy input frame
mjSpec* origin = model->FindSpec(mjs_getString(other.model->spec.modelname));
frames.push_back(new mjCFrame(other));
frames.back()->body = this;
frames.back()->model = model;
frames.back()->compiler = origin ? &origin->compiler : &model->spec.compiler;
frames.back()->frame = other.frame;
frames.back()->NameSpace(other.model);
int i = frames.size();
@@ -931,9 +936,11 @@ void mjCBody::CopyList(std::vector<T*>& dst, const std::vector<T*>& src,
if (pframe && !pframe->IsAncestor(src[i]->frame)) {
continue; // skip if the element is not inside pframe
}
mjSpec* origin = model->FindSpec(mjs_getString(src[i]->model->spec.modelname));
dst.push_back(new T(*src[i]));
dst.back()->body = this;
dst.back()->model = model;
dst.back()->compiler = origin ? &origin->compiler : &model->spec.compiler;
dst.back()->id = -1;
dst.back()->classname = src[i]->classname;
@@ -1413,8 +1420,8 @@ void mjCBody::InertiaFromGeom(void) {
// select geoms based on group
sel.clear();
for (int i=0; i<geoms.size(); i++) {
if (geoms[i]->group>=model->inertiagrouprange[0] &&
geoms[i]->group<=model->inertiagrouprange[1]) {
if (geoms[i]->group>=compiler->inertiagrouprange[0] &&
geoms[i]->group<=compiler->inertiagrouprange[1]) {
sel.push_back(geoms[i]);
}
}
@@ -1559,7 +1566,7 @@ void mjCBody::Compile(void) {
// check and process orientation alternatives for body
if (alt.type != mjORIENTATION_QUAT) {
const char* err = ResolveOrientation(quat, model->degree, model->eulerseq, alt);
const char* err = ResolveOrientation(quat, compiler->degree, compiler->eulerseq, alt);
if (err) {
throw mjCError(this, "error '%s' in frame alternative", err);
}
@@ -1582,7 +1589,7 @@ void mjCBody::Compile(void) {
}
if (ialt.type != mjORIENTATION_QUAT) {
const char* err = ResolveOrientation(iquat, model->degree, model->eulerseq, ialt);
const char* err = ResolveOrientation(iquat, compiler->degree, compiler->eulerseq, ialt);
if (err) {
throw mjCError(this, "error '%s' in inertia alternative", err);
}
@@ -1591,15 +1598,15 @@ void mjCBody::Compile(void) {
// compile all geoms
for (int i=0; i<geoms.size(); i++) {
geoms[i]->inferinertia = id>0 &&
(!explicitinertial || model->inertiafromgeom == mjINERTIAFROMGEOM_TRUE) &&
geoms[i]->spec.group >= model->inertiagrouprange[0] &&
geoms[i]->spec.group <= model->inertiagrouprange[1];
(!explicitinertial || compiler->inertiafromgeom == mjINERTIAFROMGEOM_TRUE) &&
geoms[i]->spec.group >= compiler->inertiagrouprange[0] &&
geoms[i]->spec.group <= compiler->inertiagrouprange[1];
geoms[i]->Compile();
}
// set inertial frame from geoms if necessary
if (id>0 && (model->inertiafromgeom==mjINERTIAFROMGEOM_TRUE ||
(!mjuu_defined(ipos[0]) && model->inertiafromgeom==mjINERTIAFROMGEOM_AUTO))) {
if (id>0 && (compiler->inertiafromgeom==mjINERTIAFROMGEOM_TRUE ||
(!mjuu_defined(ipos[0]) && compiler->inertiafromgeom==mjINERTIAFROMGEOM_AUTO))) {
InertiaFromGeom();
}
@@ -1612,10 +1619,10 @@ void mjCBody::Compile(void) {
// check and correct mass and inertia
if (id>0) {
// fix minimum
mass = std::max(mass, model->boundmass);
inertia[0] = std::max(inertia[0], model->boundinertia);
inertia[1] = std::max(inertia[1], model->boundinertia);
inertia[2] = std::max(inertia[2], model->boundinertia);
mass = std::max(mass, compiler->boundmass);
inertia[0] = std::max(inertia[0], compiler->boundinertia);
inertia[1] = std::max(inertia[1], compiler->boundinertia);
inertia[2] = std::max(inertia[2], compiler->boundinertia);
// check for negative values
if (mass<0 || inertia[0]<0 || inertia[1]<0 ||inertia[2]<0) {
@@ -1626,7 +1633,7 @@ void mjCBody::Compile(void) {
if (inertia[0] + inertia[1] < inertia[2] ||
inertia[0] + inertia[2] < inertia[1] ||
inertia[1] + inertia[2] < inertia[0]) {
if (model->balanceinertia) {
if (compiler->balanceinertia) {
inertia[0] = inertia[1] = inertia[2] = (inertia[0] + inertia[1] + inertia[2])/3.0;
} else {
throw mjCError(this, "inertia must satisfy A + B >= C; use 'balanceinertia' to fix");
@@ -1654,7 +1661,7 @@ void mjCBody::Compile(void) {
bodies.empty() && // no child bodies AND
(joints[0]->spec.align == 1 || // either joint.align="true"
(joints[0]->spec.align == 2 && // or joint.align="auto"
model->alignfree))); // and compiler.align="true"
compiler->alignfree))); // and compiler->align="true"
// free-joint alignment, phase 1 (this body + child geoms)
double ipos_inverse[3], iquat_inverse[4];
@@ -1740,7 +1747,7 @@ void mjCBody::Compile(void) {
}
// if discarding visual geoms, use explicit inertias
if (model->discardvisual) {
if (compiler->discardvisual) {
for (int j=0; j<geoms.size(); j++) {
if (geoms[j]->IsVisual()) {
explicitinertial = true;
@@ -1782,6 +1789,7 @@ mjCFrame::mjCFrame(mjCModel* _model, mjCFrame* _frame) {
elemtype = mjOBJ_FRAME;
compiled = false;
model = _model;
if (_model) compiler = &_model->spec.compiler;
body = NULL;
frame = _frame ? _frame : NULL;
last_attached = nullptr;
@@ -1905,7 +1913,7 @@ void mjCFrame::Compile() {
}
CopyFromSpec();
const char* err = ResolveOrientation(quat, model->spec.degree, model->spec.eulerseq, alt);
const char* err = ResolveOrientation(quat, compiler->degree, compiler->eulerseq, alt);
if (err) {
throw mjCError(this, "orientation specification error '%s' in site %d", err, id);
}
@@ -1940,6 +1948,7 @@ mjCJoint::mjCJoint(mjCModel* _model, mjCDef* _def) {
// set model, def
model = _model;
if (_model) compiler = &_model->spec.compiler;
classname = _def ? _def->name : "main";
// point to local
@@ -2069,7 +2078,7 @@ int mjCJoint::Compile(void) {
// otherwise if limited is auto, check consistency wrt auto-limits
else if (limited == mjLIMITED_AUTO) {
bool hasrange = !(range[0]==0 && range[1]==0);
checklimited(this, model->autolimits, "joint", "", limited, hasrange);
checklimited(this, compiler->autolimits, "joint", "", limited, hasrange);
}
// resolve limits
@@ -2083,7 +2092,7 @@ int mjCJoint::Compile(void) {
}
// convert limits to radians
if (model->degree && (type==mjJNT_HINGE || type==mjJNT_BALL)) {
if (compiler->degree && (type==mjJNT_HINGE || type==mjJNT_BALL)) {
if (range[0]) {
range[0] *= mjPI/180.0;
}
@@ -2100,7 +2109,7 @@ int mjCJoint::Compile(void) {
// otherwise if actfrclimited is auto, check consistency wrt auto-limits
else if (actfrclimited == mjLIMITED_AUTO) {
bool hasrange = !(actfrcrange[0]==0 && actfrcrange[1]==0);
checklimited(this, model->autolimits, "joint", "", actfrclimited, hasrange);
checklimited(this, compiler->autolimits, "joint", "", actfrclimited, hasrange);
}
// resolve actuator force range limits
@@ -2144,7 +2153,7 @@ int mjCJoint::Compile(void) {
}
// convert reference angles to radians for hinge joints
if (type==mjJNT_HINGE && model->degree) {
if (type==mjJNT_HINGE && compiler->degree) {
ref *= mjPI/180.0;
springref *= mjPI/180.0;
}
@@ -2193,6 +2202,7 @@ mjCGeom::mjCGeom(mjCModel* _model, mjCDef* _def) {
// set model, def
model = _model;
if (_model) compiler = &_model->spec.compiler;
classname = _def ? _def->name : "main";
// point to local
@@ -2892,7 +2902,7 @@ void mjCGeom::Compile(void) {
// not 'fromto': try alternative
else {
const char* err = ResolveOrientation(quat, model->degree, model->eulerseq, alt);
const char* err = ResolveOrientation(quat, compiler->degree, compiler->eulerseq, alt);
if (err) {
throw mjCError(this, "orientation specification error '%s' in geom %d", err, id);
}
@@ -3034,6 +3044,7 @@ mjCSite::mjCSite(mjCModel* _model, mjCDef* _def) {
// set model, def
model = _model;
if (_model) compiler = &_model->spec.compiler;
classname = _def ? _def->name : "main";
}
@@ -3140,7 +3151,7 @@ void mjCSite::Compile(void) {
// alternative orientation
else {
const char* err = ResolveOrientation(quat, model->degree, model->eulerseq, alt);
const char* err = ResolveOrientation(quat, compiler->degree, compiler->eulerseq, alt);
if (err) {
throw mjCError(this, "orientation specification error '%s' in site %d", err, id);
}
@@ -3179,6 +3190,7 @@ mjCCamera::mjCCamera(mjCModel* _model, mjCDef* _def) {
// set model, def
model = _model;
if (_model) compiler = &_model->spec.compiler;
classname = _def ? _def->name : "main";
// point to local
@@ -3248,7 +3260,7 @@ void mjCCamera::Compile(void) {
userdata_.resize(model->nuser_cam);
// process orientation specifications
const char* err = ResolveOrientation(quat, model->degree, model->eulerseq, alt);
const char* err = ResolveOrientation(quat, compiler->degree, compiler->eulerseq, alt);
if (err) {
throw mjCError(this, "orientation specification error '%s' in camera %d", err, id);
}
@@ -3330,6 +3342,7 @@ mjCLight::mjCLight(mjCModel* _model, mjCDef* _def) {
// set model, def
model = _model;
if (_model) compiler = &_model->spec.compiler;
classname = _def ? _def->name : "main";
PointToLocal();
@@ -3423,6 +3436,7 @@ mjCHField::mjCHField(mjCModel* _model) {
// set model pointer
model = _model;
if (_model) compiler = &_model->spec.compiler;
// clear variables
data.clear();
@@ -3678,6 +3692,7 @@ mjCTexture::mjCTexture(mjCModel* _model) {
// set model pointer
model = _model;
if (_model) compiler = &_model->spec.compiler;
// clear user settings: single file
spec_file_.clear();
@@ -4511,6 +4526,7 @@ mjCMaterial::mjCMaterial(mjCModel* _model, mjCDef* _def) {
}
model = _model;
if (_model) compiler = &_model->spec.compiler;
classname = _def ? _def->name : "main";
PointToLocal();
@@ -4597,6 +4613,7 @@ mjCPair::mjCPair(mjCModel* _model, mjCDef* _def) {
// set model, def
model = _model;
if (_model) compiler = &_model->spec.compiler;
classname = _def ? _def->name : "main";
// point to local
@@ -4817,6 +4834,7 @@ void mjCPair::Compile(void) {
mjCBodyPair::mjCBodyPair(mjCModel* _model) {
// set model pointer
model = _model;
if (_model) compiler = &_model->spec.compiler;
elemtype = mjOBJ_EXCLUDE;
// set defaults
@@ -4955,6 +4973,7 @@ mjCEquality::mjCEquality(mjCModel* _model, mjCDef* _def) {
// set model, def
model = _model;
if (_model) compiler = &_model->spec.compiler;
classname = _def ? _def->name : "main";
// point to local
@@ -5116,6 +5135,7 @@ mjCTendon::mjCTendon(mjCModel* _model, mjCDef* _def) {
// set model, def
model = _model;
if (_model) compiler = &_model->spec.compiler;
classname = _def ? _def->name : "main";
// point to local
@@ -5201,6 +5221,7 @@ mjCTendon::~mjCTendon() {
void mjCTendon::SetModel(mjCModel* _model) {
model = _model;
if (_model) compiler = &_model->spec.compiler;
for (int i=0; i<path.size(); i++) {
path[i]->model = _model;
}
@@ -5423,7 +5444,7 @@ void mjCTendon::Compile(void) {
// if limited is auto, set to 1 if range is specified, otherwise unlimited
if (limited == mjLIMITED_AUTO) {
bool hasrange = !(range[0]==0 && range[1]==0);
checklimited(this, model->autolimits, "tendon", "", limited, hasrange);
checklimited(this, compiler->autolimits, "tendon", "", limited, hasrange);
}
// check limits
@@ -5447,6 +5468,7 @@ mjCWrap::mjCWrap(mjCModel* _model, mjCTendon* _tendon) {
// set model and tendon pointer
model = _model;
if (_model) compiler = &_model->spec.compiler;
tendon = _tendon;
// clear variables
@@ -5591,6 +5613,7 @@ mjCActuator::mjCActuator(mjCModel* _model, mjCDef* _def) {
// set model, def
model = _model;
if (_model) compiler = &_model->spec.compiler;
classname = _def ? _def->name : "main";
// in case this actuator is not compiled
@@ -5846,15 +5869,15 @@ void mjCActuator::Compile(void) {
// if limited is auto, check for inconsistency wrt to autolimits
if (forcelimited == mjLIMITED_AUTO) {
bool hasrange = !(forcerange[0]==0 && forcerange[1]==0);
checklimited(this, model->autolimits, "actuator", "force", forcelimited, hasrange);
checklimited(this, compiler->autolimits, "actuator", "force", forcelimited, hasrange);
}
if (ctrllimited == mjLIMITED_AUTO) {
bool hasrange = !(ctrlrange[0]==0 && ctrlrange[1]==0);
checklimited(this, model->autolimits, "actuator", "ctrl", ctrllimited, hasrange);
checklimited(this, compiler->autolimits, "actuator", "ctrl", ctrllimited, hasrange);
}
if (actlimited == mjLIMITED_AUTO) {
bool hasrange = !(actrange[0]==0 && actrange[1]==0);
checklimited(this, model->autolimits, "actuator", "act", actlimited, hasrange);
checklimited(this, compiler->autolimits, "actuator", "act", actlimited, hasrange);
}
// check limits
@@ -5951,6 +5974,7 @@ mjCSensor::mjCSensor(mjCModel* _model) {
// set model
model = _model;
if (_model) compiler = &_model->spec.compiler;
// clear private variables
spec_objname_.clear();
@@ -6477,6 +6501,7 @@ mjCNumeric::mjCNumeric(mjCModel* _model) {
// set model pointer
model = _model;
if (_model) compiler = &_model->spec.compiler;
// clear variables
spec_data_.clear();
@@ -6566,6 +6591,7 @@ mjCText::mjCText(mjCModel* _model) {
// set model pointer
model = _model;
if (_model) compiler = &_model->spec.compiler;
// clear variables
spec_data_.clear();
@@ -6643,6 +6669,7 @@ mjCTuple::mjCTuple(mjCModel* _model) {
// set model pointer
model = _model;
if (_model) compiler = &_model->spec.compiler;
// clear variables
spec_objtype_.clear();
@@ -6776,6 +6803,7 @@ mjCKey::mjCKey(mjCModel* _model) {
// set model pointer
model = _model;
if (_model) compiler = &_model->spec.compiler;
// clear variables
spec_qpos_.clear();
@@ -6952,6 +6980,7 @@ mjCPlugin::mjCPlugin(mjCModel* _model) {
plugin_slot = -1;
parent = this;
model = _model;
if (_model) compiler = &_model->spec.compiler;
name.clear();
plugin_name.clear();