Table-driven attribute reading: rebase the reader on generated rows.

Every mechanical attribute read in MJCF now derives from mjcf.schema.
generate_read_table.py emits typed mjXAttr rows (mjcf_read_table.inc,
doc_test-gated) binding each attribute to its spec struct field; field
offsets are offsetof() expressions, so binding mistakes are compile
errors, and the field's C type -- parsed from the headers -- selects the
row kind, so mjtNum-versus-double is decided by the struct, not the
schema. mjXReader::ReadAttrTable is the generic loop; its static core
also serves the section parsers and records XML-authored fields via
mjs_setAuthored for attach conflict resolution. Row kinds cover
strings, string lists, numeric scalars and vectors (exact and ranged),
enums (int- and byte-width), bitwise flag sets, bools, unbounded typed
vectors, fixed char arrays, and identity constants declared by 'set'.
The rows are inline variables, and carry the writing=custom flag,
because the writer will share them.

The keyword maps the rows reference are generated too: the ~48
hand-written mjMap tables become mjcf_map.h, one map and size constant
per enum as C++17 inline variables, retiring the hand-maintained
extern block in xml_base.h. Map names follow the schema enum names
(fluid->fluidshape, TFAuto->FalseTrueAuto, FAuto->FalseAuto,
joint->jointtype, geom->geomtype, jac->jacobian); all maps are
key-order- and value-identical to the hand tables they replace, and
bool_map is hand-emitted (the bool type is built in, not a schema
enum).

The OneX() parsers reduce to genuine irregulars, schema-marked as
reading=custom: orientation alternatives, file attributes (VFS and
asset-dir context), the actuator shorthand remappings and per-type
input maps, springlength's one-value copy, mesh builtin construction,
hfield elevation, texture cube files, flexcomp seeding, the memory
suffix parse, and the flag bit families. All 41 sensors that are pure
identity-plus-references -- including the frame family and insidesite
-- dispatch through a generated tag table; frame-sensor
objtype/reftype vocabulary tightens from the full mju_str2Type
namespace to the documented body/xbody/geom/site/camera subset, so an
invalid keyword now fails at parse time instead of compile time. The
equality family and both tendon types read shared group rows; the
twelve actuator shorthands share the general rows, with per-tag
legality enforced by the schema check. Sections bind non-mjs structs,
the visual sub-sections reaching their anonymous sub-structs through
member paths declared by an element-level field= facet.

Latent irregularities surfaced by the migration and preserved via
schema declarations or remnants: key's name is set even when absent,
eulerseq and gridlayout are fixed char arrays (chars[n], arity in
characters), gridlayout's length-must-match-gridsize stays a
value-conditional remnant, and constructor-style elements (tendon
wraps, asset model, replicate, attach) are annotated as such -- their
attributes are arguments, not field writes.

Two coherence tests guard the schema against the C sources: every
schema enum constant must be a member of the C enum it claims, and
every C member must be a keyword, a count sentinel, or a documented
exemption; and generate_default_table.py emits one row per defaulted
attribute (mjcf_default_table.inc), compared by SchemaDefaultsTest
against a freshly-constructed spec -- the schema cannot disagree with
the C default-constructors without failing the suite.

Verified: doc_test regenerates and diffs every artifact; the full
suite; and an A/B harness compiling the model corpus against the
pre-migration reader -- saved XML and binary models are byte-identical.
PiperOrigin-RevId: 958075724
Change-Id: I9715fe4deeb438eec988fd5084d74ba8b466b10b
This commit is contained in:
Yuval Tassa
2026-08-02 17:24:11 -07:00
committed by Copybara-Service
parent 790f8fac30
commit 4278c7b0cd
14 changed files with 3131 additions and 1668 deletions
+285
View File
@@ -0,0 +1,285 @@
// Copyright 2026 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// GENERATED FILE, DO NOT EDIT. Generated from src/xml/mjcf.schema by
// doc/generate/generate_default_table.py; test/doc/doc_test.py checks
// freshness.
//
// One row per schema attribute with a declared default, binding the declared
// values to the bound field. SchemaDefaultsTest compares every row against a
// freshly-constructed spec: the schema's defaults must agree with the C
// default-constructors. Rows are {attr, offset, kind, len, ndecl, values};
// values beyond ndecl are expected to be zero; kind: 0=double 1=float 2=int
// 3=byte 4=mjtNum.
// clang-format off
struct mjXDefaultEntry {
const char* attr;
int offset;
int kind;
int len;
int ndecl;
double value[8];
};
struct mjXDefaultTable {
const char* structname;
const mjXDefaultEntry* entries;
int n;
};
static const mjXDefaultEntry kDefaults_mjOption[] = {
{"timestep", (int)offsetof(mjOption, timestep), 4, 1, 1, {0.002}},
{"impratio", (int)offsetof(mjOption, impratio), 4, 1, 1, {1.0}},
{"tolerance", (int)offsetof(mjOption, tolerance), 4, 1, 1, {1e-08}},
{"ls_tolerance", (int)offsetof(mjOption, ls_tolerance), 4, 1, 1, {0.01}},
{"noslip_tolerance", (int)offsetof(mjOption, noslip_tolerance), 4, 1, 1, {1e-06}},
{"ccd_tolerance", (int)offsetof(mjOption, ccd_tolerance), 4, 1, 1, {1e-06}},
{"sleep_tolerance", (int)offsetof(mjOption, sleep_tolerance), 4, 1, 1, {0.001}},
{"gravity", (int)offsetof(mjOption, gravity), 4, 3, 3, {0.0, 0.0, -9.81}},
{"wind", (int)offsetof(mjOption, wind), 4, 3, 3, {0.0, 0.0, 0.0}},
{"magnetic", (int)offsetof(mjOption, magnetic), 4, 3, 3, {0.0, -0.5, 0.0}},
{"o_friction", (int)offsetof(mjOption, o_friction), 4, 5, 5, {1.0, 1.0, 0.005, 0.0001, 0.0001}},
{"integrator", (int)offsetof(mjOption, integrator), 2, 1, 1, {(double)mjINT_EULER}},
{"cone", (int)offsetof(mjOption, cone), 2, 1, 1, {(double)mjCONE_PYRAMIDAL}},
{"jacobian", (int)offsetof(mjOption, jacobian), 2, 1, 1, {(double)mjJAC_AUTO}},
{"solver", (int)offsetof(mjOption, solver), 2, 1, 1, {(double)mjSOL_NEWTON}},
{"iterations", (int)offsetof(mjOption, iterations), 2, 1, 1, {100.0}},
{"ls_iterations", (int)offsetof(mjOption, ls_iterations), 2, 1, 1, {50.0}},
{"ccd_iterations", (int)offsetof(mjOption, ccd_iterations), 2, 1, 1, {35.0}},
{"sdf_iterations", (int)offsetof(mjOption, sdf_iterations), 2, 1, 1, {10.0}},
{"sdf_initpoints", (int)offsetof(mjOption, sdf_initpoints), 2, 1, 1, {40.0}},
};
static const mjXDefaultEntry kDefaults_mjVisual_global[] = {
{"cameraid", (int)offsetof(mjVisual, global.cameraid), 2, 1, 1, {-1.0}},
{"orthographic", (int)offsetof(mjVisual, global.orthographic), 2, 1, 1, {0}},
{"fovy", (int)offsetof(mjVisual, global.fovy), 1, 1, 1, {45.0}},
{"ipd", (int)offsetof(mjVisual, global.ipd), 1, 1, 1, {0.068}},
{"azimuth", (int)offsetof(mjVisual, global.azimuth), 1, 1, 1, {90.0}},
{"elevation", (int)offsetof(mjVisual, global.elevation), 1, 1, 1, {-45.0}},
{"linewidth", (int)offsetof(mjVisual, global.linewidth), 1, 1, 1, {1.0}},
{"glow", (int)offsetof(mjVisual, global.glow), 1, 1, 1, {0.3}},
{"offwidth", (int)offsetof(mjVisual, global.offwidth), 2, 1, 1, {640.0}},
{"offheight", (int)offsetof(mjVisual, global.offheight), 2, 1, 1, {480.0}},
{"realtime", (int)offsetof(mjVisual, global.realtime), 1, 1, 1, {1.0}},
{"ellipsoidinertia", (int)offsetof(mjVisual, global.ellipsoidinertia), 2, 1, 1, {0}},
{"bvactive", (int)offsetof(mjVisual, global.bvactive), 2, 1, 1, {1}},
};
static const mjXDefaultEntry kDefaults_mjVisual_headlight[] = {
{"ambient", (int)offsetof(mjVisual, headlight.ambient), 1, 3, 3, {0.1, 0.1, 0.1}},
{"diffuse", (int)offsetof(mjVisual, headlight.diffuse), 1, 3, 3, {0.4, 0.4, 0.4}},
{"specular", (int)offsetof(mjVisual, headlight.specular), 1, 3, 3, {0.5, 0.5, 0.5}},
{"active", (int)offsetof(mjVisual, headlight.active), 2, 1, 1, {1.0}},
};
static const mjXDefaultEntry kDefaults_mjVisual_map[] = {
{"stiffness", (int)offsetof(mjVisual, map.stiffness), 1, 1, 1, {100.0}},
{"stiffnessrot", (int)offsetof(mjVisual, map.stiffnessrot), 1, 1, 1, {500.0}},
{"force", (int)offsetof(mjVisual, map.force), 1, 1, 1, {0.005}},
{"torque", (int)offsetof(mjVisual, map.torque), 1, 1, 1, {0.1}},
{"alpha", (int)offsetof(mjVisual, map.alpha), 1, 1, 1, {0.3}},
{"fogstart", (int)offsetof(mjVisual, map.fogstart), 1, 1, 1, {3.0}},
{"fogend", (int)offsetof(mjVisual, map.fogend), 1, 1, 1, {10.0}},
{"znear", (int)offsetof(mjVisual, map.znear), 1, 1, 1, {0.01}},
{"zfar", (int)offsetof(mjVisual, map.zfar), 1, 1, 1, {50.0}},
{"haze", (int)offsetof(mjVisual, map.haze), 1, 1, 1, {0.3}},
{"shadowclip", (int)offsetof(mjVisual, map.shadowclip), 1, 1, 1, {1.0}},
{"shadowscale", (int)offsetof(mjVisual, map.shadowscale), 1, 1, 1, {0.6}},
{"actuatortendon", (int)offsetof(mjVisual, map.actuatortendon), 1, 1, 1, {2.0}},
};
static const mjXDefaultEntry kDefaults_mjVisual_quality[] = {
{"shadowsize", (int)offsetof(mjVisual, quality.shadowsize), 2, 1, 1, {4096.0}},
{"offsamples", (int)offsetof(mjVisual, quality.offsamples), 2, 1, 1, {4.0}},
{"numslices", (int)offsetof(mjVisual, quality.numslices), 2, 1, 1, {28.0}},
{"numstacks", (int)offsetof(mjVisual, quality.numstacks), 2, 1, 1, {16.0}},
{"numquads", (int)offsetof(mjVisual, quality.numquads), 2, 1, 1, {4.0}},
};
static const mjXDefaultEntry kDefaults_mjVisual_scale[] = {
{"forcewidth", (int)offsetof(mjVisual, scale.forcewidth), 1, 1, 1, {0.1}},
{"contactwidth", (int)offsetof(mjVisual, scale.contactwidth), 1, 1, 1, {0.3}},
{"contactheight", (int)offsetof(mjVisual, scale.contactheight), 1, 1, 1, {0.1}},
{"connect", (int)offsetof(mjVisual, scale.connect), 1, 1, 1, {0.2}},
{"com", (int)offsetof(mjVisual, scale.com), 1, 1, 1, {0.4}},
{"camera", (int)offsetof(mjVisual, scale.camera), 1, 1, 1, {0.3}},
{"light", (int)offsetof(mjVisual, scale.light), 1, 1, 1, {0.3}},
{"selectpoint", (int)offsetof(mjVisual, scale.selectpoint), 1, 1, 1, {0.2}},
{"jointlength", (int)offsetof(mjVisual, scale.jointlength), 1, 1, 1, {1.0}},
{"jointwidth", (int)offsetof(mjVisual, scale.jointwidth), 1, 1, 1, {0.1}},
{"actuatorlength", (int)offsetof(mjVisual, scale.actuatorlength), 1, 1, 1, {0.7}},
{"actuatorwidth", (int)offsetof(mjVisual, scale.actuatorwidth), 1, 1, 1, {0.2}},
{"framelength", (int)offsetof(mjVisual, scale.framelength), 1, 1, 1, {1.0}},
{"framewidth", (int)offsetof(mjVisual, scale.framewidth), 1, 1, 1, {0.1}},
{"constraint", (int)offsetof(mjVisual, scale.constraint), 1, 1, 1, {0.1}},
{"slidercrank", (int)offsetof(mjVisual, scale.slidercrank), 1, 1, 1, {0.2}},
{"frustum", (int)offsetof(mjVisual, scale.frustum), 1, 1, 1, {10.0}},
};
static const mjXDefaultEntry kDefaults_mjsActuator[] = {
{"gear", (int)offsetof(mjsActuator, gear), 0, 6, 6, {1.0, 0.0, 0.0, 0.0, 0.0, 0.0}},
{"actdim", (int)offsetof(mjsActuator, actdim), 2, 1, 1, {-1.0}},
{"dyntype", (int)offsetof(mjsActuator, dyntype), 2, 1, 1, {(double)mjDYN_NONE}},
{"gaintype", (int)offsetof(mjsActuator, gaintype), 2, 1, 1, {(double)mjGAIN_FIXED}},
{"biastype", (int)offsetof(mjsActuator, biastype), 2, 1, 1, {(double)mjBIAS_NONE}},
{"dynprm", (int)offsetof(mjsActuator, dynprm), 0, mjNDYN, 1, {1.0}},
{"gainprm", (int)offsetof(mjsActuator, gainprm), 0, mjNGAIN, 1, {1.0}},
};
static const mjXDefaultEntry kDefaults_mjsBody[] = {
{"pos", (int)offsetof(mjsBody, pos), 0, 3, 3, {0.0, 0.0, 0.0}},
{"quat", (int)offsetof(mjsBody, quat), 0, 4, 4, {1.0, 0.0, 0.0, 0.0}},
{"simple", (int)offsetof(mjsBody, simple), 3, 1, 1, {(double)1}},
};
static const mjXDefaultEntry kDefaults_mjsCamera[] = {
{"fovy", (int)offsetof(mjsCamera, fovy), 0, 1, 1, {45.0}},
{"ipd", (int)offsetof(mjsCamera, ipd), 0, 1, 1, {0.068}},
{"resolution", (int)offsetof(mjsCamera, resolution), 2, 2, 2, {1.0, 1.0}},
{"pos", (int)offsetof(mjsCamera, pos), 0, 3, 3, {0.0, 0.0, 0.0}},
{"quat", (int)offsetof(mjsCamera, quat), 0, 4, 4, {1.0, 0.0, 0.0, 0.0}},
{"mode", (int)offsetof(mjsCamera, mode), 2, 1, 1, {(double)mjCAMLIGHT_FIXED}},
};
static const mjXDefaultEntry kDefaults_mjsEquality[] = {
{"active", (int)offsetof(mjsEquality, active), 3, 1, 1, {1}},
{"solref", (int)offsetof(mjsEquality, solref), 4, mjNREF, 2, {0.02, 1.0}},
{"solimp", (int)offsetof(mjsEquality, solimp), 4, mjNIMP, 5, {0.9, 0.95, 0.001, 0.5, 2.0}},
};
static const mjXDefaultEntry kDefaults_mjsFrame[] = {
{"quat", (int)offsetof(mjsFrame, quat), 0, 4, 4, {1.0, 0.0, 0.0, 0.0}},
};
static const mjXDefaultEntry kDefaults_mjsGeom[] = {
{"type", (int)offsetof(mjsGeom, type), 2, 1, 1, {(double)mjGEOM_SPHERE}},
{"contype", (int)offsetof(mjsGeom, contype), 2, 1, 1, {1.0}},
{"conaffinity", (int)offsetof(mjsGeom, conaffinity), 2, 1, 1, {1.0}},
{"condim", (int)offsetof(mjsGeom, condim), 2, 1, 1, {3.0}},
{"friction", (int)offsetof(mjsGeom, friction), 0, 3, 3, {1.0, 0.005, 0.0001}},
{"density", (int)offsetof(mjsGeom, density), 0, 1, 1, {1000.0}},
{"solmix", (int)offsetof(mjsGeom, solmix), 0, 1, 1, {1.0}},
{"solref", (int)offsetof(mjsGeom, solref), 4, mjNREF, 2, {0.02, 1.0}},
{"solimp", (int)offsetof(mjsGeom, solimp), 4, mjNIMP, 5, {0.9, 0.95, 0.001, 0.5, 2.0}},
{"pos", (int)offsetof(mjsGeom, pos), 0, 3, 3, {0.0, 0.0, 0.0}},
{"quat", (int)offsetof(mjsGeom, quat), 0, 4, 4, {1.0, 0.0, 0.0, 0.0}},
{"fitscale", (int)offsetof(mjsGeom, fitscale), 0, 1, 1, {1.0}},
{"rgba", (int)offsetof(mjsGeom, rgba), 1, 4, 4, {0.5, 0.5, 0.5, 1.0}},
};
static const mjXDefaultEntry kDefaults_mjsJoint[] = {
{"type", (int)offsetof(mjsJoint, type), 2, 1, 1, {(double)mjJNT_HINGE}},
{"axis", (int)offsetof(mjsJoint, axis), 0, 3, 3, {0.0, 0.0, 1.0}},
};
static const mjXDefaultEntry kDefaults_mjsLight[] = {
{"castshadow", (int)offsetof(mjsLight, castshadow), 3, 1, 1, {1}},
{"active", (int)offsetof(mjsLight, active), 3, 1, 1, {1}},
{"pos", (int)offsetof(mjsLight, pos), 0, 3, 3, {0.0, 0.0, 0.0}},
{"dir", (int)offsetof(mjsLight, dir), 0, 3, 3, {0.0, 0.0, -1.0}},
{"bulbradius", (int)offsetof(mjsLight, bulbradius), 1, 1, 1, {0.02}},
{"range", (int)offsetof(mjsLight, range), 1, 1, 1, {10.0}},
{"attenuation", (int)offsetof(mjsLight, attenuation), 1, 3, 3, {1.0, 0.0, 0.0}},
{"cutoff", (int)offsetof(mjsLight, cutoff), 1, 1, 1, {45.0}},
{"exponent", (int)offsetof(mjsLight, exponent), 1, 1, 1, {10.0}},
{"diffuse", (int)offsetof(mjsLight, diffuse), 1, 3, 3, {0.7, 0.7, 0.7}},
{"specular", (int)offsetof(mjsLight, specular), 1, 3, 3, {0.3, 0.3, 0.3}},
{"mode", (int)offsetof(mjsLight, mode), 2, 1, 1, {(double)mjCAMLIGHT_FIXED}},
};
static const mjXDefaultEntry kDefaults_mjsMaterial[] = {
{"texrepeat", (int)offsetof(mjsMaterial, texrepeat), 1, 2, 2, {1.0, 1.0}},
{"specular", (int)offsetof(mjsMaterial, specular), 1, 1, 1, {0.5}},
{"shininess", (int)offsetof(mjsMaterial, shininess), 1, 1, 1, {0.5}},
{"metallic", (int)offsetof(mjsMaterial, metallic), 1, 1, 1, {-1.0}},
{"roughness", (int)offsetof(mjsMaterial, roughness), 1, 1, 1, {-1.0}},
{"rgba", (int)offsetof(mjsMaterial, rgba), 1, 4, 4, {1.0, 1.0, 1.0, 1.0}},
};
static const mjXDefaultEntry kDefaults_mjsMesh[] = {
{"refquat", (int)offsetof(mjsMesh, refquat), 0, 4, 4, {1.0, 0.0, 0.0, 0.0}},
{"scale", (int)offsetof(mjsMesh, scale), 0, 3, 3, {1.0, 1.0, 1.0}},
{"maxhullvert", (int)offsetof(mjsMesh, maxhullvert), 2, 1, 1, {-1.0}},
{"inertia", (int)offsetof(mjsMesh, inertia), 2, 1, 1, {(double)mjMESH_INERTIA_LEGACY}},
};
static const mjXDefaultEntry kDefaults_mjsPair[] = {
{"condim", (int)offsetof(mjsPair, condim), 2, 1, 1, {3.0}},
{"friction", (int)offsetof(mjsPair, friction), 0, 5, 5, {1.0, 1.0, 0.005, 0.0001, 0.0001}},
{"solref", (int)offsetof(mjsPair, solref), 4, mjNREF, 2, {0.02, 1.0}},
{"solimp", (int)offsetof(mjsPair, solimp), 4, mjNIMP, 5, {0.9, 0.95, 0.001, 0.5, 2.0}},
};
static const mjXDefaultEntry kDefaults_mjsSensor[] = {
{"datatype", (int)offsetof(mjsSensor, datatype), 2, 1, 1, {(double)mjDATATYPE_REAL}},
{"needstage", (int)offsetof(mjsSensor, needstage), 2, 1, 1, {(double)mjSTAGE_ACC}},
};
static const mjXDefaultEntry kDefaults_mjsSite[] = {
{"type", (int)offsetof(mjsSite, type), 2, 1, 1, {(double)mjGEOM_SPHERE}},
{"pos", (int)offsetof(mjsSite, pos), 0, 3, 3, {0.0, 0.0, 0.0}},
{"quat", (int)offsetof(mjsSite, quat), 0, 4, 4, {1.0, 0.0, 0.0, 0.0}},
{"size", (int)offsetof(mjsSite, size), 0, 3, 3, {0.005, 0.005, 0.005}},
{"rgba", (int)offsetof(mjsSite, rgba), 1, 4, 4, {0.5, 0.5, 0.5, 1.0}},
};
static const mjXDefaultEntry kDefaults_mjsSkin[] = {
{"rgba", (int)offsetof(mjsSkin, rgba), 1, 4, 4, {0.5, 0.5, 0.5, 1.0}},
};
static const mjXDefaultEntry kDefaults_mjsTendon[] = {
{"springlength", (int)offsetof(mjsTendon, springlength), 0, 2, 2, {-1.0, -1.0}},
{"width", (int)offsetof(mjsTendon, width), 0, 1, 1, {0.003}},
{"rgba", (int)offsetof(mjsTendon, rgba), 1, 4, 4, {0.5, 0.5, 0.5, 1.0}},
};
static const mjXDefaultEntry kDefaults_mjsTexture[] = {
{"type", (int)offsetof(mjsTexture, type), 2, 1, 1, {(double)mjTEXTURE_CUBE}},
{"colorspace", (int)offsetof(mjsTexture, colorspace), 2, 1, 1, {(double)mjCOLORSPACE_AUTO}},
{"gridsize", (int)offsetof(mjsTexture, gridsize), 2, 2, 2, {1.0, 1.0}},
{"rgb1", (int)offsetof(mjsTexture, rgb1), 0, 3, 3, {0.8, 0.8, 0.8}},
{"rgb2", (int)offsetof(mjsTexture, rgb2), 0, 3, 3, {0.5, 0.5, 0.5}},
{"random", (int)offsetof(mjsTexture, random), 0, 1, 1, {0.01}},
{"nchannel", (int)offsetof(mjsTexture, nchannel), 2, 1, 1, {3.0}},
};
static const mjXDefaultTable kDefaultTables[] = {
{"mjOption", kDefaults_mjOption, (int)(sizeof(kDefaults_mjOption) / sizeof(kDefaults_mjOption[0]))},
{"mjVisual", kDefaults_mjVisual_global, (int)(sizeof(kDefaults_mjVisual_global) / sizeof(kDefaults_mjVisual_global[0]))},
{"mjVisual", kDefaults_mjVisual_headlight, (int)(sizeof(kDefaults_mjVisual_headlight) / sizeof(kDefaults_mjVisual_headlight[0]))},
{"mjVisual", kDefaults_mjVisual_map, (int)(sizeof(kDefaults_mjVisual_map) / sizeof(kDefaults_mjVisual_map[0]))},
{"mjVisual", kDefaults_mjVisual_quality, (int)(sizeof(kDefaults_mjVisual_quality) / sizeof(kDefaults_mjVisual_quality[0]))},
{"mjVisual", kDefaults_mjVisual_scale, (int)(sizeof(kDefaults_mjVisual_scale) / sizeof(kDefaults_mjVisual_scale[0]))},
{"mjsActuator", kDefaults_mjsActuator, (int)(sizeof(kDefaults_mjsActuator) / sizeof(kDefaults_mjsActuator[0]))},
{"mjsBody", kDefaults_mjsBody, (int)(sizeof(kDefaults_mjsBody) / sizeof(kDefaults_mjsBody[0]))},
{"mjsCamera", kDefaults_mjsCamera, (int)(sizeof(kDefaults_mjsCamera) / sizeof(kDefaults_mjsCamera[0]))},
{"mjsEquality", kDefaults_mjsEquality, (int)(sizeof(kDefaults_mjsEquality) / sizeof(kDefaults_mjsEquality[0]))},
{"mjsFrame", kDefaults_mjsFrame, (int)(sizeof(kDefaults_mjsFrame) / sizeof(kDefaults_mjsFrame[0]))},
{"mjsGeom", kDefaults_mjsGeom, (int)(sizeof(kDefaults_mjsGeom) / sizeof(kDefaults_mjsGeom[0]))},
{"mjsJoint", kDefaults_mjsJoint, (int)(sizeof(kDefaults_mjsJoint) / sizeof(kDefaults_mjsJoint[0]))},
{"mjsLight", kDefaults_mjsLight, (int)(sizeof(kDefaults_mjsLight) / sizeof(kDefaults_mjsLight[0]))},
{"mjsMaterial", kDefaults_mjsMaterial, (int)(sizeof(kDefaults_mjsMaterial) / sizeof(kDefaults_mjsMaterial[0]))},
{"mjsMesh", kDefaults_mjsMesh, (int)(sizeof(kDefaults_mjsMesh) / sizeof(kDefaults_mjsMesh[0]))},
{"mjsPair", kDefaults_mjsPair, (int)(sizeof(kDefaults_mjsPair) / sizeof(kDefaults_mjsPair[0]))},
{"mjsSensor", kDefaults_mjsSensor, (int)(sizeof(kDefaults_mjsSensor) / sizeof(kDefaults_mjsSensor[0]))},
{"mjsSite", kDefaults_mjsSite, (int)(sizeof(kDefaults_mjsSite) / sizeof(kDefaults_mjsSite[0]))},
{"mjsSkin", kDefaults_mjsSkin, (int)(sizeof(kDefaults_mjsSkin) / sizeof(kDefaults_mjsSkin[0]))},
{"mjsTendon", kDefaults_mjsTendon, (int)(sizeof(kDefaults_mjsTendon) / sizeof(kDefaults_mjsTendon[0]))},
{"mjsTexture", kDefaults_mjsTexture, (int)(sizeof(kDefaults_mjsTexture) / sizeof(kDefaults_mjsTexture[0]))},
};
static const int kDefaultTablesN = (int)(sizeof(kDefaultTables) / sizeof(kDefaultTables[0]));
// clang-format on
+489
View File
@@ -0,0 +1,489 @@
// Copyright 2026 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// GENERATED FILE, DO NOT EDIT. Generated from src/xml/mjcf.schema by
// doc/generate/generate_mjcf_map.py; test/doc/doc_test.py checks freshness.
//
// Keyword maps, one per schema enum, shared by the reader, the writer and
// the generated tables. Inline variables: including this header is all a
// translation unit needs.
#ifndef MUJOCO_SRC_XML_MJCF_MAP_H_
#define MUJOCO_SRC_XML_MJCF_MAP_H_
#include <mujoco/mjspec.h>
#include <mujoco/mjtype.h>
#include "user/user_composite.h"
#include "user/user_flexcomp.h"
#include "xml/xml_util.h"
// clang-format off
// keywords of the built-in bool type (not a schema enum)
inline constexpr mjMap bool_map[] = {
{"false", 0},
{"true", 1},
};
// enum coordinate
inline constexpr mjMap coordinate_map[] = {
{"local", 0},
{"global", 1},
};
inline constexpr int coordinate_sz = 2;
// enum angle
inline constexpr mjMap angle_map[] = {
{"radian", 0},
{"degree", 1},
};
inline constexpr int angle_sz = 2;
// enum fluidshape
inline constexpr mjMap fluidshape_map[] = {
{"none", 0},
{"ellipsoid", 1},
};
inline constexpr int fluidshape_sz = 2;
// enum enable
inline constexpr mjMap enable_map[] = {
{"disable", 0},
{"enable", 1},
};
inline constexpr int enable_sz = 2;
// enum FalseTrueAuto
inline constexpr mjMap FalseTrueAuto_map[] = {
{"false", 0},
{"true", 1},
{"auto", 2},
};
inline constexpr int FalseTrueAuto_sz = 3;
// enum FalseAuto
inline constexpr mjMap FalseAuto_map[] = {
{"false", 0},
{"auto", 1},
};
inline constexpr int FalseAuto_sz = 2;
// enum bodysleep
inline constexpr mjMap bodysleep_map[] = {
{"auto", mjSLEEP_AUTO},
{"never", mjSLEEP_NEVER},
{"allowed", mjSLEEP_ALLOWED},
{"init", mjSLEEP_INIT},
};
inline constexpr int bodysleep_sz = 4;
// enum jointtype
inline constexpr mjMap jointtype_map[] = {
{"free", mjJNT_FREE},
{"ball", mjJNT_BALL},
{"slide", mjJNT_SLIDE},
{"hinge", mjJNT_HINGE},
};
inline constexpr int jointtype_sz = 4;
// enum geomtype
inline constexpr mjMap geomtype_map[] = {
{"plane", mjGEOM_PLANE},
{"hfield", mjGEOM_HFIELD},
{"sphere", mjGEOM_SPHERE},
{"capsule", mjGEOM_CAPSULE},
{"ellipsoid", mjGEOM_ELLIPSOID},
{"cylinder", mjGEOM_CYLINDER},
{"box", mjGEOM_BOX},
{"mesh", mjGEOM_MESH},
{"sdf", mjGEOM_SDF},
};
inline constexpr int geomtype_sz = 9;
// enum projection
inline constexpr mjMap projection_map[] = {
{"perspective", mjPROJ_PERSPECTIVE},
{"orthographic", mjPROJ_ORTHOGRAPHIC},
};
inline constexpr int projection_sz = 2;
// enum camlight
inline constexpr mjMap camlight_map[] = {
{"fixed", mjCAMLIGHT_FIXED},
{"track", mjCAMLIGHT_TRACK},
{"trackcom", mjCAMLIGHT_TRACKCOM},
{"targetbody", mjCAMLIGHT_TARGETBODY},
{"targetbodycom", mjCAMLIGHT_TARGETBODYCOM},
};
inline constexpr int camlight_sz = 5;
// enum lighttype
inline constexpr mjMap lighttype_map[] = {
{"spot", mjLIGHT_SPOT},
{"directional", mjLIGHT_DIRECTIONAL},
{"point", mjLIGHT_POINT},
{"image", mjLIGHT_IMAGE},
};
inline constexpr int lighttype_sz = 4;
// enum texrole
inline constexpr mjMap texrole_map[] = {
{"rgb", mjTEXROLE_RGB},
{"occlusion", mjTEXROLE_OCCLUSION},
{"roughness", mjTEXROLE_ROUGHNESS},
{"metallic", mjTEXROLE_METALLIC},
{"normal", mjTEXROLE_NORMAL},
{"opacity", mjTEXROLE_OPACITY},
{"emissive", mjTEXROLE_EMISSIVE},
{"rgba", mjTEXROLE_RGBA},
{"orm", mjTEXROLE_ORM},
};
inline constexpr int texrole_sz = 9;
// enum integrator
inline constexpr mjMap integrator_map[] = {
{"Euler", mjINT_EULER},
{"RK4", mjINT_RK4},
{"implicit", mjINT_IMPLICIT},
{"implicitfast", mjINT_IMPLICITFAST},
};
inline constexpr int integrator_sz = 4;
// enum cone
inline constexpr mjMap cone_map[] = {
{"pyramidal", mjCONE_PYRAMIDAL},
{"elliptic", mjCONE_ELLIPTIC},
};
inline constexpr int cone_sz = 2;
// enum jacobian
inline constexpr mjMap jacobian_map[] = {
{"dense", mjJAC_DENSE},
{"sparse", mjJAC_SPARSE},
{"auto", mjJAC_AUTO},
};
inline constexpr int jacobian_sz = 3;
// enum solver
inline constexpr mjMap solver_map[] = {
{"PGS", mjSOL_PGS},
{"CG", mjSOL_CG},
{"Newton", mjSOL_NEWTON},
};
inline constexpr int solver_sz = 3;
// enum equality
inline constexpr mjMap equality_map[] = {
{"connect", mjEQ_CONNECT},
{"weld", mjEQ_WELD},
{"joint", mjEQ_JOINT},
{"tendon", mjEQ_TENDON},
{"flex", mjEQ_FLEX},
{"flexvert", mjEQ_FLEXVERT},
{"flexstrain", mjEQ_FLEXSTRAIN},
{"distance", mjEQ_DISTANCE},
};
inline constexpr int equality_sz = 8;
// enum texture
inline constexpr mjMap texture_map[] = {
{"2d", mjTEXTURE_2D},
{"cube", mjTEXTURE_CUBE},
{"skybox", mjTEXTURE_SKYBOX},
};
inline constexpr int texture_sz = 3;
// enum colorspace
inline constexpr mjMap colorspace_map[] = {
{"auto", mjCOLORSPACE_AUTO},
{"linear", mjCOLORSPACE_LINEAR},
{"sRGB", mjCOLORSPACE_SRGB},
};
inline constexpr int colorspace_sz = 3;
// enum builtin
inline constexpr mjMap builtin_map[] = {
{"none", mjBUILTIN_NONE},
{"gradient", mjBUILTIN_GRADIENT},
{"checker", mjBUILTIN_CHECKER},
{"flat", mjBUILTIN_FLAT},
};
inline constexpr int builtin_sz = 4;
// enum mark
inline constexpr mjMap mark_map[] = {
{"none", mjMARK_NONE},
{"edge", mjMARK_EDGE},
{"cross", mjMARK_CROSS},
{"random", mjMARK_RANDOM},
};
inline constexpr int mark_sz = 4;
// enum dyn
inline constexpr mjMap dyn_map[] = {
{"none", mjDYN_NONE},
{"integrator", mjDYN_INTEGRATOR},
{"filter", mjDYN_FILTER},
{"filterexact", mjDYN_FILTEREXACT},
{"muscle", mjDYN_MUSCLE},
{"dcmotor", mjDYN_DCMOTOR},
{"pid", mjDYN_PID},
{"user", mjDYN_USER},
};
inline constexpr int dyn_sz = 8;
// enum dcmotorinput
inline constexpr mjMap dcmotorinput_map[] = {
{"voltage", 0},
{"position", 1},
{"velocity", 2},
};
inline constexpr int dcmotorinput_sz = 3;
// enum gain
inline constexpr mjMap gain_map[] = {
{"fixed", mjGAIN_FIXED},
{"affine", mjGAIN_AFFINE},
{"muscle", mjGAIN_MUSCLE},
{"dcmotor", mjGAIN_DCMOTOR},
{"so3", mjGAIN_SO3},
{"pid", mjGAIN_PID},
{"user", mjGAIN_USER},
};
inline constexpr int gain_sz = 7;
// enum inputchart
inline constexpr mjMap inputchart_map[] = {
{"expmap", mjCHART_EXPMAP},
{"quat", mjCHART_QUAT},
};
inline constexpr int inputchart_sz = 2;
// enum inputbit
inline constexpr mjMap inputbit_map[] = {
{"pos", mjINPUT_POS},
{"vel", mjINPUT_VEL},
{"ff", mjINPUT_FF},
};
inline constexpr int inputbit_sz = 3;
// enum bias
inline constexpr mjMap bias_map[] = {
{"none", mjBIAS_NONE},
{"affine", mjBIAS_AFFINE},
{"muscle", mjBIAS_MUSCLE},
{"dcmotor", mjBIAS_DCMOTOR},
{"so3", mjBIAS_SO3},
{"user", mjBIAS_USER},
};
inline constexpr int bias_sz = 6;
// enum interp
inline constexpr mjMap interp_map[] = {
{"zoh", 0},
{"linear", 1},
{"cubic", 2},
};
inline constexpr int interp_sz = 3;
// enum stage
inline constexpr mjMap stage_map[] = {
{"none", mjSTAGE_NONE},
{"pos", mjSTAGE_POS},
{"vel", mjSTAGE_VEL},
{"acc", mjSTAGE_ACC},
};
inline constexpr int stage_sz = 4;
// enum datatype
inline constexpr mjMap datatype_map[] = {
{"real", mjDATATYPE_REAL},
{"positive", mjDATATYPE_POSITIVE},
{"axis", mjDATATYPE_AXIS},
{"quaternion", mjDATATYPE_QUATERNION},
};
inline constexpr int datatype_sz = 4;
// enum frameobj
inline constexpr mjMap frameobj_map[] = {
{"body", mjOBJ_BODY},
{"xbody", mjOBJ_XBODY},
{"geom", mjOBJ_GEOM},
{"site", mjOBJ_SITE},
{"camera", mjOBJ_CAMERA},
};
inline constexpr int frameobj_sz = 5;
// enum condata
inline constexpr mjMap condata_map[] = {
{"found", mjCONDATA_FOUND},
{"force", mjCONDATA_FORCE},
{"torque", mjCONDATA_TORQUE},
{"dist", mjCONDATA_DIST},
{"pos", mjCONDATA_POS},
{"normal", mjCONDATA_NORMAL},
{"tangent", mjCONDATA_TANGENT},
};
inline constexpr int condata_sz = 7;
// enum raydata
inline constexpr mjMap raydata_map[] = {
{"dist", mjRAYDATA_DIST},
{"dir", mjRAYDATA_DIR},
{"origin", mjRAYDATA_ORIGIN},
{"point", mjRAYDATA_POINT},
{"normal", mjRAYDATA_NORMAL},
{"depth", mjRAYDATA_DEPTH},
};
inline constexpr int raydata_sz = 6;
// enum camout
inline constexpr mjMap camout_map[] = {
{"rgb", mjCAMOUT_RGB},
{"depth", mjCAMOUT_DEPTH},
{"distance", mjCAMOUT_DIST},
{"normal", mjCAMOUT_NORMAL},
{"segmentation", mjCAMOUT_SEG},
};
inline constexpr int camout_sz = 5;
// enum reduce
inline constexpr mjMap reduce_map[] = {
{"none", 0},
{"mindist", 1},
{"maxforce", 2},
{"netforce", 3},
};
inline constexpr int reduce_sz = 4;
// enum conflict
inline constexpr mjMap conflict_map[] = {
{"warning", mjCONFLICT_WARNING},
{"merge", mjCONFLICT_MERGE},
{"error", mjCONFLICT_ERROR},
};
inline constexpr int conflict_sz = 3;
// enum lrmode
inline constexpr mjMap lrmode_map[] = {
{"none", mjLRMODE_NONE},
{"muscle", mjLRMODE_MUSCLE},
{"muscleuser", mjLRMODE_MUSCLEUSER},
{"all", mjLRMODE_ALL},
};
inline constexpr int lrmode_sz = 4;
// enum comp
inline constexpr mjMap comp_map[] = {
{"particle", mjCOMPTYPE_PARTICLE},
{"grid", mjCOMPTYPE_GRID},
{"rope", mjCOMPTYPE_ROPE},
{"loop", mjCOMPTYPE_LOOP},
{"cable", mjCOMPTYPE_CABLE},
{"cloth", mjCOMPTYPE_CLOTH},
};
inline constexpr int comp_sz = 6;
// enum jkind
inline constexpr mjMap jkind_map[] = {
{"main", mjCOMPKIND_JOINT},
};
inline constexpr int jkind_sz = 1;
// enum shape
inline constexpr mjMap shape_map[] = {
{"s", mjCOMPSHAPE_LINE},
{"cos(s)", mjCOMPSHAPE_COS},
{"sin(s)", mjCOMPSHAPE_SIN},
{"0", mjCOMPSHAPE_ZERO},
};
inline constexpr int shape_sz = 4;
// enum meshinertia
inline constexpr mjMap meshinertia_map[] = {
{"convex", mjMESH_INERTIA_CONVEX},
{"legacy", mjMESH_INERTIA_LEGACY},
{"exact", mjMESH_INERTIA_EXACT},
{"shell", mjMESH_INERTIA_SHELL},
};
inline constexpr int meshinertia_sz = 4;
// enum meshbuiltin
inline constexpr mjMap meshbuiltin_map[] = {
{"none", mjMESH_BUILTIN_NONE},
{"sphere", mjMESH_BUILTIN_SPHERE},
{"hemisphere", mjMESH_BUILTIN_HEMISPHERE},
{"cone", mjMESH_BUILTIN_CONE},
{"supertorus", mjMESH_BUILTIN_SUPERTORUS},
{"supersphere", mjMESH_BUILTIN_SUPERSPHERE},
{"wedge", mjMESH_BUILTIN_WEDGE},
{"plate", mjMESH_BUILTIN_PLATE},
};
inline constexpr int meshbuiltin_sz = 8;
// enum fcomp
inline constexpr mjMap fcomp_map[] = {
{"grid", mjFCOMPTYPE_GRID},
{"box", mjFCOMPTYPE_BOX},
{"cylinder", mjFCOMPTYPE_CYLINDER},
{"ellipsoid", mjFCOMPTYPE_ELLIPSOID},
{"square", mjFCOMPTYPE_SQUARE},
{"disc", mjFCOMPTYPE_DISC},
{"circle", mjFCOMPTYPE_CIRCLE},
{"mesh", mjFCOMPTYPE_MESH},
{"gmsh", mjFCOMPTYPE_GMSH},
{"direct", mjFCOMPTYPE_DIRECT},
};
inline constexpr int fcomp_sz = 10;
// enum fdof
inline constexpr mjMap fdof_map[] = {
{"full", mjFCOMPDOF_FULL},
{"radial", mjFCOMPDOF_RADIAL},
{"trilinear", mjFCOMPDOF_TRILINEAR},
{"quadratic", mjFCOMPDOF_QUADRATIC},
{"2d", mjFCOMPDOF_2D},
};
inline constexpr int fdof_sz = 5;
// enum flexself
inline constexpr mjMap flexself_map[] = {
{"none", mjFLEXSELF_NONE},
{"narrow", mjFLEXSELF_NARROW},
{"bvh", mjFLEXSELF_BVH},
{"sap", mjFLEXSELF_SAP},
{"auto", mjFLEXSELF_AUTO},
};
inline constexpr int flexself_sz = 5;
// enum elastic2d
inline constexpr mjMap elastic2d_map[] = {
{"none", 0},
{"bend", 1},
{"stretch", 2},
{"both", 3},
};
inline constexpr int elastic2d_sz = 4;
// enum flexeq
inline constexpr mjMap flexeq_map[] = {
{"false", 0},
{"true", 1},
{"vert", 2},
{"strain", 3},
};
inline constexpr int flexeq_sz = 4;
// clang-format on
#endif // MUJOCO_SRC_XML_MJCF_MAP_H_
File diff suppressed because it is too large Load Diff
+36 -69
View File
@@ -24,75 +24,8 @@
#include "tinyxml2.h"
// keyword maps (defined in implementation files)
extern const int joint_sz;
extern const int bodysleep_sz;
extern const int projection_sz;
extern const int camlight_sz;
extern const int lighttype_sz;
extern const int integrator_sz;
extern const int collision_sz;
extern const int cone_sz;
extern const int jac_sz;
extern const int solver_sz;
extern const int equality_sz;
extern const int texture_sz;
extern const int colorspace_sz;
extern const int builtin_sz;
extern const int mark_sz;
extern const int dyn_sz;
extern const int inputchart_sz;
extern const int inputbit_sz;
extern const int gain_sz;
extern const int bias_sz;
extern const int interp_sz;
extern const int stage_sz;
extern const int datatype_sz;
extern const int camout_sz;
extern const int reduce_sz;
extern const int conflict_sz;
extern const mjMap angle_map[];
extern const mjMap enable_map[];
extern const mjMap bool_map[];
extern const mjMap fluid_map[];
extern const mjMap TFAuto_map[];
extern const mjMap FAuto_map[];
extern const mjMap joint_map[];
extern const mjMap bodysleep_map[];
extern const mjMap geom_map[];
extern const mjMap projection_map[];
extern const mjMap camlight_map[];
extern const mjMap lighttype_map[];
extern const mjMap integrator_map[];
extern const mjMap collision_map[];
extern const mjMap impedance_map[];
extern const mjMap reference_map[];
extern const mjMap cone_map[];
extern const mjMap jac_map[];
extern const mjMap solver_map[];
extern const mjMap equality_map[];
extern const mjMap texture_map[];
extern const mjMap colorspace_map[];
extern const mjMap texrole_map[];
extern const mjMap builtin_map[];
extern const mjMap mark_map[];
extern const mjMap dyn_map[];
extern const mjMap inputchart_map[];
extern const mjMap inputbit_map[];
extern const mjMap gain_map[];
extern const mjMap bias_map[];
extern const mjMap interp_map[];
extern const mjMap stage_map[];
extern const mjMap datatype_map[];
extern const mjMap condata_map[];
extern const mjMap raydata_map[];
extern const mjMap camout_map[];
extern const mjMap reduce_map[];
extern const mjMap meshtype_map[];
extern const mjMap meshinertia_map[];
extern const mjMap flexself_map[];
extern const mjMap elastic2d_map[];
extern const mjMap conflict_map[];
// keyword maps, one per schema enum, generated into mjcf_map.h
#include "xml/mjcf_map.h" // IWYU pragma: export
//---------------------------------- Base XML class ------------------------------------------------
@@ -119,4 +52,38 @@ class mjXBase : public mjXUtil {
mjSpec* spec; // internally-allocated model
};
// typed attribute row for table-driven reading/writing; per-element row arrays are
// generated from mjcf.schema into mjcf_read_table.inc
struct mjXAttr {
enum Kind {
kName, // element name, set via mjs_setName
kString, // mjString* field, set via mjs_setString
kStringVec, // mjStringVec* field: space-separated names
kInt, // int field
kDouble, // double field, scalar or vector
kNum, // mjtNum field, scalar or vector
kFloat, // float field, scalar or vector
kEnum, // int-sized enum field, keyword mapped through `map`
kFlags, // int field ORing several keywords through `map`
kEnumByte, // mjtByte enum field, keyword mapped through `map`
kBool, // mjtBool field, keywords true/false
kConst, // int-sized field set to `value`: what the tag implies
kDoubleVec, // mjDoubleVec* field, set via mjs_setDouble
kFloatVec, // mjFloatVec* field, set via mjs_setFloat
kIntVec, // mjIntVec* field, set via mjs_setInt
kChars, // char[len] field: text copied in place, length-checked
};
const char* attr; // XML attribute name
Kind kind;
int len; // number of values (1 = scalar); numeric kinds only
bool exact; // exactly len values, else up to len
bool required;
bool nodefault; // not read in default classes
bool handwrite; // custom save policy (writing=custom): OneX() remnant
int offset; // byte offset of the bound field; -1 for kName
const mjMap* map; // keyword map; kEnum only
int mapsz; // keyword map size; kEnum only
int value; // constant the field takes; kConst only
};
#endif // MUJOCO_SRC_XML_XML_BASE_H_
+340 -1584
View File
File diff suppressed because it is too large Load Diff
+11
View File
@@ -66,6 +66,17 @@ class mjXReader : public mjXBase {
void Sensor(tinyxml2::XMLElement* section); // sensor section
void Keyframe(tinyxml2::XMLElement* section); // keyframe section
// table-driven attribute reading: the mechanical attributes of an element,
// driven by its generated mjXAttr rows (see mjcf_read_table.inc). The
// static core handles everything except element names; the member wrapper
// adds kName handling and defaults-context awareness.
void ReadAttrTable(tinyxml2::XMLElement* elem, void* obj, mjsElement* el,
const struct mjXAttr* rows, int nrow);
static void ReadAttrTableCore(tinyxml2::XMLElement* elem, void* obj,
const struct mjXAttr* rows, int nrow,
bool skipnodefault,
const void* authored = nullptr);
// single element parsers, used in defaults and main body
void OneFlex(tinyxml2::XMLElement* elem, mjsFlex* pflex);
void OneMesh(tinyxml2::XMLElement* elem, mjsMesh* pmesh, const mjVFS* vfs);
+14 -14
View File
@@ -392,7 +392,7 @@ void mjXWriter::OneJoint(XMLElement* elem, const mjCJoint* joint, mjCDef* def,
// defaults and regular
if (joint->type != def->Joint().type) {
WriteAttrTxt(elem, "type", FindValue(joint_map, joint_sz, joint->type));
WriteAttrTxt(elem, "type", FindValue(jointtype_map, jointtype_sz, joint->type));
}
WriteAttrInt(elem, "group", joint->group, def->Joint().group);
WriteAttr(elem, "ref", 1, &joint->ref, &zero);
@@ -410,11 +410,11 @@ void mjXWriter::OneJoint(XMLElement* elem, const mjCJoint* joint, mjCDef* def,
WriteAttr(elem, "stiffness", nstiff, joint->stiffness, def->Joint().stiffness);
}
if (joint->type != mjJNT_FREE) {
WriteAttrKey(elem, "limited", TFAuto_map, 3, joint->limited, def->Joint().limited);
WriteAttrKey(elem, "limited", FalseTrueAuto_map, 3, joint->limited, def->Joint().limited);
}
WriteAttr(elem, "range", 2, joint->range, def->Joint().range);
if (joint->type != mjJNT_FREE && joint->type != mjJNT_BALL) {
WriteAttrKey(elem, "actuatorfrclimited", TFAuto_map, 3, joint->actfrclimited,
WriteAttrKey(elem, "actuatorfrclimited", FalseTrueAuto_map, 3, joint->actfrclimited,
def->Joint().actfrclimited);
}
WriteAttrKey(elem, "actuatorgravcomp", bool_map, 2, joint->actgravcomp, def->Joint().actgravcomp);
@@ -485,7 +485,7 @@ void mjXWriter::OneGeom(XMLElement* elem, const mjCGeom* geom, mjCDef* def, stri
}
// defaults and regular
WriteAttrKey(elem, "type", geom_map, mjNGEOMTYPES, geom->type, def->Geom().type);
WriteAttrKey(elem, "type", geomtype_map, mjNGEOMTYPES, geom->type, def->Geom().type);
WriteAttrInt(elem, "contype", geom->contype, def->Geom().contype);
WriteAttrInt(elem, "conaffinity", geom->conaffinity, def->Geom().conaffinity);
WriteAttrInt(elem, "condim", geom->condim, def->Geom().condim);
@@ -500,10 +500,10 @@ void mjXWriter::OneGeom(XMLElement* elem, const mjCGeom* geom, mjCDef* def, stri
WriteAttr(elem, "surfacevel", 6, geom->surfacevel, def->Geom().surfacevel, true);
WriteAttr(elem, "adhesion", 1, &geom->adhesion, &def->Geom().adhesion);
WriteAttrKey(elem, "fluidshape",
fluid_map, 2, geom->fluid_ellipsoid, def->Geom().fluid_ellipsoid);
fluidshape_map, 2, geom->fluid_ellipsoid, def->Geom().fluid_ellipsoid);
WriteAttr(elem, "fluidcoef", 5, geom->fluid_coefs, def->Geom().fluid_coefs);
if (geom->type != mjGEOM_MESH) {
WriteAttrKey(elem, "shellinertia", meshtype_map, 2, geom->typeinertia,
WriteAttrKey(elem, "shellinertia", bool_map, 2, geom->typeinertia,
def->Geom().typeinertia);
}
if (mjuu_defined(geom->mass)) {
@@ -558,7 +558,7 @@ void mjXWriter::OneSite(XMLElement* elem, const mjCSite* site, mjCDef* def, stri
// defaults and regular
WriteAttrInt(elem, "group", site->group, def->Site().group);
WriteAttrKey(elem, "type", geom_map, mjNGEOMTYPES, site->type, def->Site().type);
WriteAttrKey(elem, "type", geomtype_map, mjNGEOMTYPES, site->type, def->Site().type);
if (site->get_material() != def->Site().get_material()) {
WriteAttrTxt(elem, "material", site->get_material());
}
@@ -772,8 +772,8 @@ void mjXWriter::OneTendon(XMLElement* elem, const mjCTendon* tendon, mjCDef* def
true);
WriteAttr(elem, "solimpfriction", mjNIMP, tendon->solimp_friction, def->Tendon().solimp_friction,
true);
WriteAttrKey(elem, "limited", TFAuto_map, 3, tendon->limited, def->Tendon().limited);
WriteAttrKey(elem, "actuatorfrclimited", TFAuto_map, 3, tendon->actfrclimited, def->Tendon().actfrclimited);
WriteAttrKey(elem, "limited", FalseTrueAuto_map, 3, tendon->limited, def->Tendon().limited);
WriteAttrKey(elem, "actuatorfrclimited", FalseTrueAuto_map, 3, tendon->actfrclimited, def->Tendon().actfrclimited);
WriteAttr(elem, "range", 2, tendon->range, def->Tendon().range);
WriteAttr(elem, "actuatorfrcrange", 2, tendon->actfrcrange, def->Tendon().actfrcrange);
WriteAttr(elem, "margin", 1, &tendon->margin, &def->Tendon().margin);
@@ -863,11 +863,11 @@ void mjXWriter::OneActuator(XMLElement* elem, const mjCActuator* actuator, mjCDe
WriteAttrInt(elem, "nsample", actuator->nsample, def->Actuator().nsample);
WriteAttrKey(elem, "interp", interp_map, interp_sz, actuator->interp, def->Actuator().interp);
WriteAttr(elem, "delay", 1, &actuator->delay, &def->Actuator().delay);
WriteAttrKey(elem, "ctrllimited", TFAuto_map, 3, actuator->ctrllimited, def->Actuator().ctrllimited);
WriteAttrKey(elem, "ctrllimited", FalseTrueAuto_map, 3, actuator->ctrllimited, def->Actuator().ctrllimited);
WriteAttr(elem, "ctrlrange", 2, actuator->ctrlrange, def->Actuator().ctrlrange);
WriteAttrKey(elem, "forcelimited", TFAuto_map, 3, actuator->forcelimited, def->Actuator().forcelimited);
WriteAttrKey(elem, "forcelimited", FalseTrueAuto_map, 3, actuator->forcelimited, def->Actuator().forcelimited);
WriteAttr(elem, "forcerange", 2, actuator->forcerange, def->Actuator().forcerange);
WriteAttrKey(elem, "actlimited", TFAuto_map, 3, actuator->actlimited, def->Actuator().actlimited);
WriteAttrKey(elem, "actlimited", FalseTrueAuto_map, 3, actuator->actlimited, def->Actuator().actlimited);
WriteAttr(elem, "actrange", 2, actuator->actrange, def->Actuator().actrange);
WriteAttr(elem, "lengthrange", 2, actuator->lengthrange, def->Actuator().lengthrange);
WriteAttr(elem, "gear", 6, actuator->gear, def->Actuator().gear);
@@ -1086,7 +1086,7 @@ void mjXWriter::Option(XMLElement* root) {
model->option.integrator, opt.integrator);
WriteAttrKey(section, "cone", cone_map, cone_sz,
model->option.cone, opt.cone);
WriteAttrKey(section, "jacobian", jac_map, jac_sz,
WriteAttrKey(section, "jacobian", jacobian_map, jacobian_sz,
model->option.jacobian, opt.jacobian);
WriteAttrKey(section, "solver", solver_map, solver_sz,
model->option.solver, opt.solver);
@@ -1743,7 +1743,7 @@ void mjXWriter::Body(XMLElement* elem, mjCBody* body, mjCFrame* frame, string_vi
}
// simple optimization
WriteAttrKey(elem, "simple", FAuto_map, 2, body->simple, 1);
WriteAttrKey(elem, "simple", FalseAuto_map, 2, body->simple, 1);
// userdata
WriteVector(elem, "user", body->get_userdata());