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:
committed by
Copybara-Service
parent
1043633cc3
commit
159f23e6b4
@@ -69,7 +69,13 @@ mjSpec* mj_makeSpec() {
|
||||
|
||||
// copy model
|
||||
mjSpec* mj_copySpec(const mjSpec* s) {
|
||||
mjCModel* modelC = new mjCModel(*static_cast<mjCModel*>(s->element));
|
||||
mjCModel* modelC = nullptr;
|
||||
try {
|
||||
modelC = new mjCModel(*static_cast<mjCModel*>(s->element));
|
||||
} catch (mjCError& e) {
|
||||
mju_error("Failed to copy spec: %s", e.message);
|
||||
return nullptr;
|
||||
}
|
||||
return &modelC->spec;
|
||||
}
|
||||
|
||||
@@ -177,7 +183,8 @@ mjsBody* mjs_attachToSite(mjsSite* parent, const mjsBody* child,
|
||||
frame->spec.quat[1] = site->spec.quat[1];
|
||||
frame->spec.quat[2] = site->spec.quat[2];
|
||||
frame->spec.quat[3] = site->spec.quat[3];
|
||||
mjs_resolveOrientation(frame->spec.quat, spec->degree, spec->eulerseq, &site->spec.alt);
|
||||
mjs_resolveOrientation(frame->spec.quat, spec->compiler.degree,
|
||||
spec->compiler.eulerseq, &site->spec.alt);
|
||||
return mjs_attachBody(&frame->spec, child, prefix, suffix);
|
||||
}
|
||||
|
||||
|
||||
@@ -98,8 +98,9 @@ mjCFlexcomp::mjCFlexcomp(void) {
|
||||
|
||||
|
||||
// make flexcomp object
|
||||
bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) {
|
||||
mjCModel* model = (mjCModel*)spec->element;
|
||||
bool mjCFlexcomp::Make(mjsBody* body, char* error, int error_sz) {
|
||||
mjCModel* model = static_cast<mjCBody*>(body->element)->model;
|
||||
mjsCompiler* compiler = static_cast<mjCBody*>(body->element)->compiler;
|
||||
mjsFlex* dflex = def.spec.flex;
|
||||
|
||||
bool radial = (type == mjFCOMPTYPE_BOX ||
|
||||
@@ -147,7 +148,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) {
|
||||
}
|
||||
|
||||
// compute orientation
|
||||
const char* alterr = mjs_resolveOrientation(quat, model->spec.degree, model->spec.eulerseq, &alt);
|
||||
const char* alterr = mjs_resolveOrientation(quat, compiler->degree, compiler->eulerseq, &alt);
|
||||
if (alterr) {
|
||||
return comperr(error, alterr, error_sz);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ typedef enum _mjtFcompType {
|
||||
class mjCFlexcomp {
|
||||
public:
|
||||
mjCFlexcomp(void);
|
||||
bool Make(mjSpec* spec, mjsBody* body, char* error, int error_sz);
|
||||
bool Make(mjsBody* body, char* error, int error_sz);
|
||||
|
||||
bool MakeGrid(char* error, int error_sz);
|
||||
bool MakeBox(char* error, int error_sz);
|
||||
|
||||
+11
-11
@@ -33,17 +33,17 @@ void mjs_defaultSpec(mjSpec* spec) {
|
||||
spec->stat.center[0] = mjNAN;
|
||||
|
||||
// compiler settings
|
||||
spec->autolimits = 1;
|
||||
spec->settotalmass = -1;
|
||||
spec->degree = 1;
|
||||
spec->eulerseq[0] = 'x';
|
||||
spec->eulerseq[1] = 'y';
|
||||
spec->eulerseq[2] = 'z';
|
||||
spec->convexhull = 1;
|
||||
spec->usethread = 1;
|
||||
spec->inertiafromgeom = mjINERTIAFROMGEOM_AUTO;
|
||||
spec->inertiagrouprange[1] = mjNGROUP-1;
|
||||
mj_defaultLROpt(&spec->LRopt);
|
||||
spec->compiler.autolimits = 1;
|
||||
spec->compiler.settotalmass = -1;
|
||||
spec->compiler.degree = 1;
|
||||
spec->compiler.eulerseq[0] = 'x';
|
||||
spec->compiler.eulerseq[1] = 'y';
|
||||
spec->compiler.eulerseq[2] = 'z';
|
||||
spec->compiler.convexhull = 1;
|
||||
spec->compiler.usethread = 1;
|
||||
spec->compiler.inertiafromgeom = mjINERTIAFROMGEOM_AUTO;
|
||||
spec->compiler.inertiagrouprange[1] = mjNGROUP-1;
|
||||
mj_defaultLROpt(&spec->compiler.LRopt);
|
||||
|
||||
// engine data
|
||||
mj_defaultOption(&spec->option);
|
||||
|
||||
@@ -563,7 +563,7 @@ void mjCMesh::Compile(const mjVFS* vfs) {
|
||||
}
|
||||
|
||||
// make graph describing convex hull
|
||||
if ((model->convexhull && needhull_) || face_.empty()) {
|
||||
if ((model->compiler.convexhull && needhull_) || face_.empty()) {
|
||||
MakeGraph();
|
||||
}
|
||||
|
||||
@@ -739,7 +739,7 @@ void mjCMesh::FitGeom(mjCGeom* geom, double* meshpos) {
|
||||
mjuu_copyvec(meshpos, GetPosPtr(geom->typeinertia), 3);
|
||||
|
||||
// use inertial box
|
||||
if (!model->fitaabb) {
|
||||
if (!model->compiler.fitaabb) {
|
||||
// get inertia box type (shell or volume)
|
||||
double* boxsz = GetInertiaBoxPtr(geom->typeinertia);
|
||||
switch (geom->type) {
|
||||
|
||||
+17
-29
@@ -227,8 +227,10 @@ void mjCModel::CopyList(std::vector<T*>& dest,
|
||||
}
|
||||
// copy the element from the other model to this model
|
||||
source[i]->ForgetKeyframes();
|
||||
mjSpec* origin = FindSpec(mjs_getString(source[i]->model->spec.modelname));
|
||||
dest.push_back(candidate);
|
||||
dest.back()->model = this;
|
||||
dest.back()->compiler = origin ? &origin->compiler : &spec.compiler;
|
||||
dest.back()->id = -1;
|
||||
}
|
||||
if (!dest.empty()) {
|
||||
@@ -354,20 +356,6 @@ static bool IsPluginActive(
|
||||
|
||||
|
||||
mjCModel& mjCModel::operator+=(const mjCModel& other) {
|
||||
// TODO: use compiler settings stored in specs_ during compilation
|
||||
std::string msg = "cannot attach mjSpecs with incompatible compiler/";
|
||||
if (other.spec.degree != spec.degree) {
|
||||
throw mjCError(nullptr, (msg + "angle attribute").c_str());
|
||||
}
|
||||
if (other.spec.autolimits != spec.autolimits) {
|
||||
throw mjCError(nullptr, (msg + "autolimits attribute").c_str());
|
||||
}
|
||||
if (other.spec.eulerseq[0] != spec.eulerseq[0] ||
|
||||
other.spec.eulerseq[1] != spec.eulerseq[1] ||
|
||||
other.spec.eulerseq[2] != spec.eulerseq[2]) {
|
||||
throw mjCError(nullptr, (msg + "eulerseq attribute").c_str());
|
||||
}
|
||||
|
||||
// create global lists
|
||||
mjCBody *world = bodies_[0];
|
||||
ResetTreeLists();
|
||||
@@ -1784,8 +1772,8 @@ void mjCModel::LengthRange(mjModel* m, mjData* data) {
|
||||
mjOption saveopt = m->opt;
|
||||
m->opt.disableflags = mjDSBL_FRICTIONLOSS | mjDSBL_CONTACT | mjDSBL_PASSIVE |
|
||||
mjDSBL_GRAVITY | mjDSBL_ACTUATION;
|
||||
if (LRopt.timestep>0) {
|
||||
m->opt.timestep = LRopt.timestep;
|
||||
if (compiler.LRopt.timestep>0) {
|
||||
m->opt.timestep = compiler.LRopt.timestep;
|
||||
}
|
||||
|
||||
// number of threads available
|
||||
@@ -1800,14 +1788,14 @@ void mjCModel::LengthRange(mjModel* m, mjData* data) {
|
||||
m->actuator_biastype[i]==mjBIAS_MUSCLE);
|
||||
int isuser = (m->actuator_gaintype[i]==mjGAIN_USER ||
|
||||
m->actuator_biastype[i]==mjBIAS_USER);
|
||||
if ((LRopt.mode==mjLRMODE_NONE) ||
|
||||
(LRopt.mode==mjLRMODE_MUSCLE && !ismuscle) ||
|
||||
(LRopt.mode==mjLRMODE_MUSCLEUSER && !ismuscle && !isuser)) {
|
||||
if ((compiler.LRopt.mode==mjLRMODE_NONE) ||
|
||||
(compiler.LRopt.mode==mjLRMODE_MUSCLE && !ismuscle) ||
|
||||
(compiler.LRopt.mode==mjLRMODE_MUSCLEUSER && !ismuscle && !isuser)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// use existing length range if available
|
||||
if (LRopt.useexisting &&
|
||||
if (compiler.LRopt.useexisting &&
|
||||
(m->actuator_lengthrange[2*i] < m->actuator_lengthrange[2*i+1])) {
|
||||
continue;
|
||||
}
|
||||
@@ -1817,10 +1805,10 @@ void mjCModel::LengthRange(mjModel* m, mjData* data) {
|
||||
}
|
||||
|
||||
// single thread
|
||||
if (!usethread || cnt<2 || nthread<2) {
|
||||
if (!compiler.usethread || cnt<2 || nthread<2) {
|
||||
char err[200];
|
||||
for (int i=0; i<m->nu; i++) {
|
||||
if (!mj_setLengthRange(m, data, i, &LRopt, err, 200)) {
|
||||
if (!mj_setLengthRange(m, data, i, &compiler.LRopt, err, 200)) {
|
||||
throw mjCError(0, "%s", err);
|
||||
}
|
||||
}
|
||||
@@ -1844,7 +1832,7 @@ void mjCModel::LengthRange(mjModel* m, mjData* data) {
|
||||
// prepare thread function arguments, clear errors
|
||||
LRThreadArg arg[kMaxCompilerThreads];
|
||||
for (int i=0; i<nthread; i++) {
|
||||
LRThreadArg temp = {m, pdata[i], i*num, num, &LRopt, err[i], 200};
|
||||
LRThreadArg temp = {m, pdata[i], i*num, num, &compiler.LRopt, err[i], 200};
|
||||
arg[i] = temp;
|
||||
err[i][0] = 0;
|
||||
}
|
||||
@@ -3914,7 +3902,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
||||
ProcessLists();
|
||||
|
||||
// delete visual assets
|
||||
if (discardvisual) {
|
||||
if (compiler.discardvisual) {
|
||||
DeleteAll(materials_);
|
||||
DeleteTexcoord(flexes_);
|
||||
DeleteTexcoord(meshes_);
|
||||
@@ -3937,7 +3925,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
||||
SetNuser();
|
||||
|
||||
// compile meshes (needed for geom compilation)
|
||||
if (usethread && meshes_.size() > 1) {
|
||||
if (compiler.usethread && meshes_.size() > 1) {
|
||||
// multi-threaded mesh compile
|
||||
CompileMeshes(vfs);
|
||||
} else {
|
||||
@@ -3981,10 +3969,10 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
||||
reassignid(excludes_);
|
||||
|
||||
// resolve asset references, compute sizes
|
||||
IndexAssets(discardvisual);
|
||||
IndexAssets(compiler.discardvisual);
|
||||
SetSizes();
|
||||
// fuse static if enabled
|
||||
if (fusestatic) {
|
||||
if (compiler.fusestatic) {
|
||||
FuseStatic();
|
||||
}
|
||||
|
||||
@@ -4144,8 +4132,8 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
||||
CopyObjects(m);
|
||||
|
||||
// scale mass
|
||||
if (settotalmass>0) {
|
||||
mj_setTotalmass(m, settotalmass);
|
||||
if (compiler.settotalmass>0) {
|
||||
mj_setTotalmass(m, compiler.settotalmass);
|
||||
}
|
||||
|
||||
// set arena size into m->narena
|
||||
|
||||
+57
-28
@@ -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();
|
||||
|
||||
|
||||
@@ -212,7 +212,8 @@ class mjCBase : public mjCBase_ {
|
||||
mjCBase& operator=(const mjCBase& other);
|
||||
|
||||
mjCFrame* frame; // pointer to frame transformation
|
||||
mjCModel* model; // pointer to model that created object
|
||||
mjCModel* model; // pointer to model that owns object
|
||||
mjsCompiler* compiler; // pointer to the compiler options
|
||||
|
||||
virtual ~mjCBase() = default; // destructor
|
||||
|
||||
|
||||
+2
-2
@@ -365,8 +365,8 @@ mjSpec* ParseXML(const char* filename, const mjVFS* vfs,
|
||||
// set reasonable default for parsing a URDF
|
||||
// this is separate from the Parser to allow multiple URDFs to be loaded.
|
||||
spec->strippath = true;
|
||||
spec->fusestatic = true;
|
||||
spec->discardvisual = true;
|
||||
spec->compiler.fusestatic = true;
|
||||
spec->compiler.discardvisual = true;
|
||||
|
||||
parser.SetModel(spec);
|
||||
parser.Parse(root);
|
||||
|
||||
@@ -972,19 +972,19 @@ void mjXReader::Compiler(XMLElement* section, mjSpec* spec) {
|
||||
|
||||
// top-level attributes
|
||||
if (MapValue(section, "autolimits", &n, bool_map, 2)) {
|
||||
spec->autolimits = (n==1);
|
||||
spec->compiler.autolimits = (n==1);
|
||||
}
|
||||
ReadAttr(section, "boundmass", 1, &spec->boundmass, text);
|
||||
ReadAttr(section, "boundinertia", 1, &spec->boundinertia, text);
|
||||
ReadAttr(section, "settotalmass", 1, &spec->settotalmass, text);
|
||||
ReadAttr(section, "boundmass", 1, &spec->compiler.boundmass, text);
|
||||
ReadAttr(section, "boundinertia", 1, &spec->compiler.boundinertia, text);
|
||||
ReadAttr(section, "settotalmass", 1, &spec->compiler.settotalmass, text);
|
||||
if (MapValue(section, "balanceinertia", &n, bool_map, 2)) {
|
||||
spec->balanceinertia = (n==1);
|
||||
spec->compiler.balanceinertia = (n==1);
|
||||
}
|
||||
if (MapValue(section, "strippath", &n, bool_map, 2)) {
|
||||
spec->strippath = (n==1);
|
||||
}
|
||||
if (MapValue(section, "fitaabb", &n, bool_map, 2)) {
|
||||
spec->fitaabb = (n==1);
|
||||
spec->compiler.fitaabb = (n==1);
|
||||
}
|
||||
if (MapValue(section, "coordinate", &n, coordinate_map, 2)) {
|
||||
if (n==1) {
|
||||
@@ -993,13 +993,13 @@ void mjXReader::Compiler(XMLElement* section, mjSpec* spec) {
|
||||
}
|
||||
}
|
||||
if (MapValue(section, "angle", &n, angle_map, 2)) {
|
||||
spec->degree = (n==1);
|
||||
spec->compiler.degree = (n==1);
|
||||
}
|
||||
if (ReadAttrTxt(section, "eulerseq", text)) {
|
||||
if (text.size()!=3) {
|
||||
throw mjXError(section, "euler format must have length 3");
|
||||
}
|
||||
memcpy(spec->eulerseq, text.c_str(), 3);
|
||||
memcpy(spec->compiler.eulerseq, text.c_str(), 3);
|
||||
}
|
||||
if (ReadAttrTxt(section, "assetdir", text)) {
|
||||
mjs_setString(spec->meshdir, text.c_str());
|
||||
@@ -1014,27 +1014,27 @@ void mjXReader::Compiler(XMLElement* section, mjSpec* spec) {
|
||||
mjs_setString(spec->texturedir, texturedir.c_str());
|
||||
}
|
||||
if (MapValue(section, "discardvisual", &n, bool_map, 2)) {
|
||||
spec->discardvisual = (n==1);
|
||||
spec->compiler.discardvisual = (n==1);
|
||||
}
|
||||
if (MapValue(section, "convexhull", &n, bool_map, 2)) {
|
||||
spec->convexhull = (n==1);
|
||||
spec->compiler.convexhull = (n==1);
|
||||
}
|
||||
if (MapValue(section, "usethread", &n, bool_map, 2)) {
|
||||
spec->usethread = (n==1);
|
||||
spec->compiler.usethread = (n==1);
|
||||
}
|
||||
if (MapValue(section, "fusestatic", &n, bool_map, 2)) {
|
||||
spec->fusestatic = (n==1);
|
||||
spec->compiler.fusestatic = (n==1);
|
||||
}
|
||||
MapValue(section, "inertiafromgeom", &spec->inertiafromgeom, TFAuto_map, 3);
|
||||
ReadAttr(section, "inertiagrouprange", 2, spec->inertiagrouprange, text);
|
||||
MapValue(section, "inertiafromgeom", &spec->compiler.inertiafromgeom, TFAuto_map, 3);
|
||||
ReadAttr(section, "inertiagrouprange", 2, spec->compiler.inertiagrouprange, text);
|
||||
if (MapValue(section, "alignfree", &n, bool_map, 2)) {
|
||||
spec->alignfree = (n==1);
|
||||
spec->compiler.alignfree = (n==1);
|
||||
}
|
||||
|
||||
// lengthrange subelement
|
||||
XMLElement* elem = FindSubElem(section, "lengthrange");
|
||||
if (elem) {
|
||||
mjLROpt* opt = &(spec->LRopt);
|
||||
mjLROpt* opt = &(spec->compiler.LRopt);
|
||||
|
||||
// flags
|
||||
MapValue(elem, "mode", &opt->mode, lrmode_map, lrmode_sz);
|
||||
@@ -2759,7 +2759,7 @@ void mjXReader::OneFlexcomp(XMLElement* elem, mjsBody* body, const mjVFS* vfs) {
|
||||
|
||||
// make flexcomp
|
||||
char error[200];
|
||||
bool res = fcomp.Make(spec, body, error, 200);
|
||||
bool res = fcomp.Make(body, error, 200);
|
||||
|
||||
// throw error
|
||||
if (!res) {
|
||||
@@ -3575,7 +3575,7 @@ void mjXReader::Body(XMLElement* section, mjsBody* body, mjsFrame* frame,
|
||||
alt.type = mjORIENTATION_EULER;
|
||||
mjuu_copyvec(alt.euler, euler, 3);
|
||||
double rotation[4] = {1, 0, 0, 0};
|
||||
mjs_resolveOrientation(rotation, spec->degree, spec->eulerseq, &alt);
|
||||
mjs_resolveOrientation(rotation, spec->compiler.degree, spec->compiler.eulerseq, &alt);
|
||||
|
||||
// read childdef
|
||||
mjsDefault* childdef = 0;
|
||||
@@ -3610,7 +3610,7 @@ void mjXReader::Body(XMLElement* section, mjsBody* body, mjsFrame* frame,
|
||||
alt.euler[0] = i*euler[0];
|
||||
alt.euler[1] = i*euler[1];
|
||||
alt.euler[2] = i*euler[2];
|
||||
mjs_resolveOrientation(quat, spec->degree, spec->eulerseq, &alt);
|
||||
mjs_resolveOrientation(quat, spec->compiler.degree, spec->compiler.eulerseq, &alt);
|
||||
mjuu_setvec(pframe->quat, quat[0], quat[1], quat[2], quat[3]);
|
||||
|
||||
// process suffix
|
||||
|
||||
@@ -920,8 +920,8 @@ void mjXWriter::Compiler(XMLElement* root) {
|
||||
XMLElement* section = InsertEnd(root, "compiler");
|
||||
|
||||
// settings
|
||||
if (!model->convexhull) {
|
||||
WriteAttrTxt(section, "convexhull", FindValue(bool_map, 2, model->convexhull));
|
||||
if (!model->compiler.convexhull) {
|
||||
WriteAttrTxt(section, "convexhull", FindValue(bool_map, 2, model->compiler.convexhull));
|
||||
}
|
||||
WriteAttrTxt(section, "angle", "radian");
|
||||
if (!model->get_meshdir().empty()) {
|
||||
@@ -930,20 +930,20 @@ void mjXWriter::Compiler(XMLElement* root) {
|
||||
if (!model->get_texturedir().empty()) {
|
||||
WriteAttrTxt(section, "texturedir", model->get_texturedir());
|
||||
}
|
||||
if (!model->usethread) {
|
||||
if (!model->compiler.usethread) {
|
||||
WriteAttrTxt(section, "usethread", "false");
|
||||
}
|
||||
|
||||
if (model->boundmass) {
|
||||
WriteAttr(section, "boundmass", 1, &model->boundmass);
|
||||
if (model->compiler.boundmass) {
|
||||
WriteAttr(section, "boundmass", 1, &model->compiler.boundmass);
|
||||
}
|
||||
if (model->boundinertia) {
|
||||
WriteAttr(section, "boundinertia", 1, &model->boundinertia);
|
||||
if (model->compiler.boundinertia) {
|
||||
WriteAttr(section, "boundinertia", 1, &model->compiler.boundinertia);
|
||||
}
|
||||
if (model->alignfree) {
|
||||
if (model->compiler.alignfree) {
|
||||
WriteAttrTxt(section, "alignfree", "true");
|
||||
}
|
||||
if (!model->autolimits) {
|
||||
if (!model->compiler.autolimits) {
|
||||
WriteAttrTxt(section, "autolimits", "false");
|
||||
}
|
||||
}
|
||||
@@ -1611,7 +1611,7 @@ void mjXWriter::Body(XMLElement* elem, mjCBody* body, mjCFrame* frame, string_vi
|
||||
WriteVector(elem, "user", body->get_userdata());
|
||||
|
||||
// write inertial
|
||||
if (body->explicitinertial && model->inertiafromgeom!=mjINERTIAFROMGEOM_TRUE) {
|
||||
if (body->explicitinertial && model->compiler.inertiafromgeom!=mjINERTIAFROMGEOM_TRUE) {
|
||||
XMLElement* inertial = InsertEnd(elem, "inertial");
|
||||
WriteAttr(inertial, "pos", 3, body->ipos);
|
||||
WriteAttr(inertial, "quat", 4, body->iquat, unitq);
|
||||
|
||||
+2
-2
@@ -109,7 +109,7 @@ void mjXURDF::Parse(
|
||||
}
|
||||
|
||||
// enforce required compiler defaults for URDF
|
||||
spec->degree = false;
|
||||
spec->compiler.degree = false;
|
||||
|
||||
// get model name
|
||||
std::string modelname;
|
||||
@@ -316,7 +316,7 @@ void mjXURDF::Body(XMLElement* body_elem) {
|
||||
}
|
||||
}
|
||||
// create geom if not discarded
|
||||
if (!spec->discardvisual) {
|
||||
if (!spec->compiler.discardvisual) {
|
||||
pgeom = Geom(elem, pbody, false);
|
||||
|
||||
// save color
|
||||
|
||||
Reference in New Issue
Block a user