From 8b9fa2674c1e6aee327e461037550494958468e9 Mon Sep 17 00:00:00 2001 From: Kyle Bayes Date: Thu, 13 Nov 2025 03:40:36 -0800 Subject: [PATCH] Use std::vector instead of array in MJCF schema. PiperOrigin-RevId: 831787681 Change-Id: I8093b8b10260daecb830e49319eda798e2dd2da5 --- src/xml/xml_native_reader.cc | 340 +++++++++++++++++------------------ src/xml/xml_native_reader.h | 3 +- src/xml/xml_util.cc | 6 +- src/xml/xml_util.h | 6 +- test/xml/xml_schema_test.cc | 23 +-- 5 files changed, 182 insertions(+), 196 deletions(-) diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index e64d7fd1..47413f3e 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -97,20 +97,20 @@ static void UpdateString(string& psuffix, int count, int i) { //---------------------------------- MJCF schema --------------------------------------------------- -const char* MJCF[nMJCF][mjXATTRNUM] = { -{"mujoco", "!", "1", "model"}, +std::vector MJCF[nMJCF] = { +{"mujoco", "!", "model"}, {"<"}, - {"compiler", "*", "20", "autolimits", "boundmass", "boundinertia", "settotalmass", + {"compiler", "*", "autolimits", "boundmass", "boundinertia", "settotalmass", "balanceinertia", "strippath", "coordinate", "angle", "fitaabb", "eulerseq", "meshdir", "texturedir", "discardvisual", "usethread", "fusestatic", "inertiafromgeom", "inertiagrouprange", "saveinertial", "assetdir", "alignfree"}, {"<"}, - {"lengthrange", "?", "10", "mode", "useexisting", "uselimit", + {"lengthrange", "?", "mode", "useexisting", "uselimit", "accel", "maxforce", "timeconst", "timestep", "inttotal", "interval", "tolrange"}, {">"}, - {"option", "*", "27", + {"option", "*", "timestep", "impratio", "tolerance", "ls_tolerance", "noslip_tolerance", "ccd_tolerance", "sleep_tolerance", "gravity", "wind", "magnetic", "density", "viscosity", "o_margin", "o_solref", "o_solimp", "o_friction", @@ -118,391 +118,391 @@ const char* MJCF[nMJCF][mjXATTRNUM] = { "solver", "iterations", "ls_iterations", "noslip_iterations", "ccd_iterations", "sdf_iterations", "sdf_initpoints", "actuatorgroupdisable"}, {"<"}, - {"flag", "?", "25", "constraint", "equality", "frictionloss", "limit", "contact", + {"flag", "?", "constraint", "equality", "frictionloss", "limit", "contact", "spring", "damper", "gravity", "clampctrl", "warmstart", "filterparent", "actuation", "refsafe", "sensor", "midphase", "eulerdamp", "autoreset", "nativeccd", "island", "override", "energy", "fwdinv", "invdiscrete", "multiccd", "sleep"}, {">"}, - {"size", "*", "14", "memory", "njmax", "nconmax", "nstack", "nuserdata", "nkey", + {"size", "*", "memory", "njmax", "nconmax", "nstack", "nuserdata", "nkey", "nuser_body", "nuser_jnt", "nuser_geom", "nuser_site", "nuser_cam", "nuser_tendon", "nuser_actuator", "nuser_sensor"}, - {"visual", "*", "0"}, + {"visual", "*"}, {"<"}, - {"global", "?", "13", "cameraid", "orthographic", "fovy", "ipd", "azimuth", "elevation", + {"global", "?", "cameraid", "orthographic", "fovy", "ipd", "azimuth", "elevation", "linewidth", "glow", "offwidth", "offheight", "realtime", "ellipsoidinertia", "bvactive"}, - {"quality", "?", "5", "shadowsize", "offsamples", "numslices", "numstacks", + {"quality", "?", "shadowsize", "offsamples", "numslices", "numstacks", "numquads"}, - {"headlight", "?", "4", "ambient", "diffuse", "specular", "active"}, - {"map", "?", "13", "stiffness", "stiffnessrot", "force", "torque", "alpha", + {"headlight", "?", "ambient", "diffuse", "specular", "active"}, + {"map", "?", "stiffness", "stiffnessrot", "force", "torque", "alpha", "fogstart", "fogend", "znear", "zfar", "haze", "shadowclip", "shadowscale", "actuatortendon"}, - {"scale", "?", "17", "forcewidth", "contactwidth", "contactheight", "connect", "com", + {"scale", "?", "forcewidth", "contactwidth", "contactheight", "connect", "com", "camera", "light", "selectpoint", "jointlength", "jointwidth", "actuatorlength", "actuatorwidth", "framelength", "framewidth", "constraint", "slidercrank", "frustum"}, - {"rgba", "?", "25", "fog", "haze", "force", "inertia", "joint", + {"rgba", "?", "fog", "haze", "force", "inertia", "joint", "actuator", "actuatornegative", "actuatorpositive", "com", "camera", "light", "selectpoint", "connect", "contactpoint", "contactforce", "contactfriction", "contacttorque", "contactgap", "rangefinder", "constraint", "slidercrank", "crankbroken", "frustum", "bv", "bvactive"}, {">"}, - {"statistic", "*", "5", "meaninertia", "meanmass", "meansize", "extent", "center"}, + {"statistic", "*", "meaninertia", "meanmass", "meansize", "extent", "center"}, - {"default", "R", "1", "class"}, + {"default", "R", "class"}, {"<"}, - {"mesh", "?", "3", "scale", "maxhullvert", "inertia"}, - {"material", "?", "10", "texture", "emission", "specular", "shininess", + {"mesh", "?", "scale", "maxhullvert", "inertia"}, + {"material", "?", "texture", "emission", "specular", "shininess", "reflectance", "metallic", "roughness", "rgba", "texrepeat", "texuniform"}, - {"joint", "?", "22", "type", "group", "pos", "axis", "springdamper", + {"joint", "?", "type", "group", "pos", "axis", "springdamper", "limited", "actuatorfrclimited", "solreflimit", "solimplimit", "solreffriction", "solimpfriction", "stiffness", "range", "actuatorfrcrange", "actuatorgravcomp", "margin", "ref", "springref", "armature", "damping", "frictionloss", "user"}, - {"geom", "?", "31", "type", "pos", "quat", "contype", "conaffinity", "condim", + {"geom", "?", "type", "pos", "quat", "contype", "conaffinity", "condim", "group", "priority", "size", "material", "friction", "mass", "density", "shellinertia", "solmix", "solref", "solimp", "margin", "gap", "fromto", "axisangle", "xyaxes", "zaxis", "euler", "hfield", "mesh", "fitscale", "rgba", "fluidshape", "fluidcoef", "user"}, - {"site", "?", "13", "type", "group", "pos", "quat", "material", + {"site", "?", "type", "group", "pos", "quat", "material", "size", "fromto", "axisangle", "xyaxes", "zaxis", "euler", "rgba", "user"}, - {"camera", "?", "17", "orthographic", "fovy", "ipd", "resolution", "pos", "quat", + {"camera", "?", "orthographic", "fovy", "ipd", "resolution", "pos", "quat", "axisangle", "xyaxes", "zaxis", "euler", "mode", "focal", "focalpixel", "principal", "principalpixel", "sensorsize", "user"}, - {"light", "?", "16", "pos", "dir", "bulbradius", "intensity", "range", + {"light", "?", "pos", "dir", "bulbradius", "intensity", "range", "directional", "type", "castshadow", "active", "attenuation", "cutoff", "exponent", "ambient", "diffuse", "specular", "mode"}, - {"pair", "?", "7", "condim", "friction", "solref", "solreffriction", "solimp", + {"pair", "?", "condim", "friction", "solref", "solreffriction", "solimp", "gap", "margin"}, - {"equality", "?", "3", "active", "solref", "solimp"}, - {"tendon", "?", "16", "group", "limited", "range", + {"equality", "?", "active", "solref", "solimp"}, + {"tendon", "?", "group", "limited", "range", "solreflimit", "solimplimit", "solreffriction", "solimpfriction", "frictionloss", "springlength", "width", "material", "margin", "stiffness", "damping", "rgba", "user"}, - {"general", "?", "18", "ctrllimited", "forcelimited", "actlimited", "ctrlrange", + {"general", "?", "ctrllimited", "forcelimited", "actlimited", "ctrlrange", "forcerange", "actrange", "gear", "cranklength", "user", "group", "actdim", "dyntype", "gaintype", "biastype", "dynprm", "gainprm", "biasprm", "actearly"}, - {"motor", "?", "8", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", + {"motor", "?", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", "gear", "cranklength", "user", "group"}, - {"position", "?", "13", "ctrllimited", "forcelimited", "ctrlrange", "inheritrange", + {"position", "?", "ctrllimited", "forcelimited", "ctrlrange", "inheritrange", "forcerange", "gear", "cranklength", "user", "group", "kp", "kv", "dampratio", "timeconst"}, - {"velocity", "?", "9", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", + {"velocity", "?", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", "gear", "cranklength", "user", "group", "kv"}, - {"intvelocity", "?", "13", "ctrllimited", "forcelimited", + {"intvelocity", "?", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", "actrange", "inheritrange", "gear", "cranklength", "user", "group", "kp", "kv", "dampratio"}, - {"damper", "?", "8", "forcelimited", "ctrlrange", "forcerange", + {"damper", "?", "forcelimited", "ctrlrange", "forcerange", "gear", "cranklength", "user", "group", "kv"}, - {"cylinder", "?", "12", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", + {"cylinder", "?", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", "gear", "cranklength", "user", "group", "timeconst", "area", "diameter", "bias"}, - {"muscle", "?", "17", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", + {"muscle", "?", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", "gear", "cranklength", "user", "group", "timeconst", "range", "force", "scale", "lmin", "lmax", "vmax", "fpmax", "fvmax"}, - {"adhesion", "?", "6", "forcelimited", "ctrlrange", "forcerange", + {"adhesion", "?", "forcelimited", "ctrlrange", "forcerange", "gain", "user", "group"}, {">"}, - {"extension", "*", "0"}, + {"extension", "*"}, {"<"}, - {"plugin", "*", "1", "plugin"}, + {"plugin", "*", "plugin"}, {"<"}, - {"instance", "*", "1", "name"}, + {"instance", "*", "name"}, {"<"}, - {"config", "*", "2", "key", "value"}, + {"config", "*", "key", "value"}, {">"}, {">"}, {">"}, - {"custom", "*", "0"}, + {"custom", "*"}, {"<"}, - {"numeric", "*", "3", "name", "size", "data"}, - {"text", "*", "2", "name", "data"}, - {"tuple", "*", "1", "name"}, + {"numeric", "*", "name", "size", "data"}, + {"text", "*", "name", "data"}, + {"tuple", "*", "name"}, {"<"}, - {"element", "*", "3", "objtype", "objname", "prm"}, + {"element", "*", "objtype", "objname", "prm"}, {">"}, {">"}, - {"asset", "*", "0"}, + {"asset", "*"}, {"<"}, - {"mesh", "*", "17", "name", "class", "content_type", "file", "vertex", "normal", + {"mesh", "*", "name", "class", "content_type", "file", "vertex", "normal", "texcoord", "face", "refpos", "refquat", "scale", "smoothnormal", "maxhullvert", "inertia", "builtin", "params", "material"}, {"<"}, - {"plugin", "*", "2", "plugin", "instance"}, + {"plugin", "*", "plugin", "instance"}, {"<"}, - {"config", "*", "2", "key", "value"}, + {"config", "*", "key", "value"}, {">"}, {">"}, - {"hfield", "*", "7", "name", "content_type", "file", "nrow", "ncol", "size", "elevation"}, - {"skin", "*", "9", "name", "file", "material", "rgba", "inflate", + {"hfield", "*", "name", "content_type", "file", "nrow", "ncol", "size", "elevation"}, + {"skin", "*", "name", "file", "material", "rgba", "inflate", "vertex", "texcoord", "face", "group"}, {"<"}, - {"bone", "*", "5", "body", "bindpos", "bindquat", "vertid", "vertweight"}, + {"bone", "*", "body", "bindpos", "bindquat", "vertid", "vertweight"}, {">"}, - {"texture", "*", "24", "name", "type", "colorspace", "content_type", "file", "gridsize", + {"texture", "*", "name", "type", "colorspace", "content_type", "file", "gridsize", "gridlayout", "fileright", "fileleft", "fileup", "filedown", "filefront", "fileback", "builtin", "rgb1", "rgb2", "mark", "markrgb", "random", "width", "height", "hflip", "vflip", "nchannel"}, - {"material", "*", "12", "name", "class", "texture", "texrepeat", "texuniform", + {"material", "*", "name", "class", "texture", "texrepeat", "texuniform", "emission", "specular", "shininess", "reflectance", "metallic", "roughness", "rgba"}, {"<"}, - {"layer", "*", "2", "texture", "role"}, + {"layer", "*", "texture", "role"}, {">"}, - {"model", "*", "3", "name", "file", "content_type"}, + {"model", "*", "name", "file", "content_type"}, {">"}, - {"body", "R", "12", "name", "childclass", "pos", "quat", "mocap", + {"body", "R", "name", "childclass", "pos", "quat", "mocap", "axisangle", "xyaxes", "zaxis", "euler", "gravcomp", "sleep", "user"}, {"<"}, - {"inertial", "?", "9", "pos", "quat", "mass", "diaginertia", + {"inertial", "?", "pos", "quat", "mass", "diaginertia", "axisangle", "xyaxes", "zaxis", "euler", "fullinertia"}, - {"joint", "*", "24", "name", "class", "type", "group", "pos", "axis", + {"joint", "*", "name", "class", "type", "group", "pos", "axis", "springdamper", "limited", "actuatorfrclimited", "solreflimit", "solimplimit", "solreffriction", "solimpfriction", "stiffness", "range", "actuatorfrcrange", "actuatorgravcomp", "margin", "ref", "springref", "armature", "damping", "frictionloss", "user"}, - {"freejoint", "*", "3", "name", "group", "align"}, - {"geom", "*", "33", "name", "class", "type", "contype", "conaffinity", "condim", + {"freejoint", "*", "name", "group", "align"}, + {"geom", "*", "name", "class", "type", "contype", "conaffinity", "condim", "group", "priority", "size", "material", "friction", "mass", "density", "shellinertia", "solmix", "solref", "solimp", "margin", "gap", "fromto", "pos", "quat", "axisangle", "xyaxes", "zaxis", "euler", "hfield", "mesh", "fitscale", "rgba", "fluidshape", "fluidcoef", "user"}, {"<"}, - {"plugin", "*", "2", "plugin", "instance"}, + {"plugin", "*", "plugin", "instance"}, {"<"}, - {"config", "*", "2", "key", "value"}, + {"config", "*", "key", "value"}, {">"}, {">"}, - {"attach", "*", "3", "model", "body", "prefix"}, - {"site", "*", "15", "name", "class", "type", "group", "pos", "quat", + {"attach", "*", "model", "body", "prefix"}, + {"site", "*", "name", "class", "type", "group", "pos", "quat", "material", "size", "fromto", "axisangle", "xyaxes", "zaxis", "euler", "rgba", "user"}, - {"camera", "*", "20", "name", "class", "orthographic", "fovy", "ipd", "resolution", "pos", + {"camera", "*", "name", "class", "orthographic", "fovy", "ipd", "resolution", "pos", "quat", "axisangle", "xyaxes", "zaxis", "euler", "mode", "target", "focal", "focalpixel", "principal", "principalpixel", "sensorsize", "user"}, - {"light", "*", "20", "name", "class", "directional", "type", "castshadow", "active", + {"light", "*", "name", "class", "directional", "type", "castshadow", "active", "pos", "dir", "bulbradius", "intensity", "range", "attenuation", "cutoff", "exponent", "ambient", "diffuse", "specular", "mode", "target", "texture"}, - {"plugin", "*", "2", "plugin", "instance"}, + {"plugin", "*", "plugin", "instance"}, {"<"}, - {"config", "*", "2", "key", "value"}, + {"config", "*", "key", "value"}, {">"}, - {"composite", "*", "9", "prefix", "type", "count", "offset", + {"composite", "*", "prefix", "type", "count", "offset", "vertex", "initial", "curve", "size", "quat"}, {"<"}, - {"joint", "*", "17", "kind", "group", "stiffness", "damping", "armature", + {"joint", "*", "kind", "group", "stiffness", "damping", "armature", "solreffix", "solimpfix", "type", "axis", "limited", "range", "margin", "solreflimit", "solimplimit", "frictionloss", "solreffriction", "solimpfriction"}, - {"skin", "?", "6", "texcoord", "material", "group", "rgba", "inflate", "subgrid"}, - {"geom", "?", "17", "type", "contype", "conaffinity", "condim", + {"skin", "?", "texcoord", "material", "group", "rgba", "inflate", "subgrid"}, + {"geom", "?", "type", "contype", "conaffinity", "condim", "group", "priority", "size", "material", "rgba", "friction", "mass", "density", "solmix", "solref", "solimp", "margin", "gap"}, - {"site", "?", "4", "group", "size", "material", "rgba"}, - {"plugin", "*", "2", "plugin", "instance"}, + {"site", "?", "group", "size", "material", "rgba"}, + {"plugin", "*", "plugin", "instance"}, {"<"}, - {"config", "*", "2", "key", "value"}, + {"config", "*", "key", "value"}, {">"}, {">"}, - {"flexcomp", "*", "26", "name", "type", "group", "dim", "dof", + {"flexcomp", "*", "name", "type", "group", "dim", "dof", "count", "spacing", "radius", "rigid", "mass", "inertiabox", "scale", "file", "point", "element", "texcoord", "material", "rgba", "flatskin", "pos", "quat", "axisangle", "xyaxes", "zaxis", "euler", "origin"}, {"<"}, - {"edge", "?", "5", "equality", "solref", "solimp", "stiffness", "damping"}, - {"elasticity", "?", "5", "young", "poisson", "damping", "thickness", "elastic2d"}, - {"contact", "?", "15", "contype", "conaffinity", "condim", "priority", + {"edge", "?", "equality", "solref", "solimp", "stiffness", "damping"}, + {"elasticity", "?", "young", "poisson", "damping", "thickness", "elastic2d"}, + {"contact", "?", "contype", "conaffinity", "condim", "priority", "friction", "solmix", "solref", "solimp", "margin", "gap", "internal", "selfcollide", "activelayers", "vertcollide", "passive"}, - {"pin", "*", "4", "id", "range", "grid", "gridrange"}, - {"plugin", "*", "2", "plugin", "instance"}, + {"pin", "*", "id", "range", "grid", "gridrange"}, + {"plugin", "*", "plugin", "instance"}, {"<"}, - {"config", "*", "2", "key", "value"}, + {"config", "*", "key", "value"}, {">"}, {">"}, {">"}, - {"deformable", "*", "0"}, + {"deformable", "*"}, {"<"}, - {"flex", "*", "13", "name", "group", "dim", "radius", "material", + {"flex", "*", "name", "group", "dim", "radius", "material", "rgba", "flatskin", "body", "vertex", "element", "texcoord", "elemtexcoord", "node"}, {"<"}, - {"contact", "?", "15", "contype", "conaffinity", "condim", "priority", + {"contact", "?", "contype", "conaffinity", "condim", "priority", "friction", "solmix", "solref", "solimp", "margin", "gap", "internal", "selfcollide", "activelayers", "vertcollide", "passive"}, - {"edge", "?", "2", "stiffness", "damping"}, - {"elasticity", "?", "5", "young", "poisson", "damping", "thickness", "elastic2d"}, + {"edge", "?", "stiffness", "damping"}, + {"elasticity", "?", "young", "poisson", "damping", "thickness", "elastic2d"}, {">"}, - {"skin", "*", "9", "name", "file", "material", "rgba", "inflate", + {"skin", "*", "name", "file", "material", "rgba", "inflate", "vertex", "texcoord", "face", "group"}, {"<"}, - {"bone", "*", "5", "body", "bindpos", "bindquat", "vertid", "vertweight"}, + {"bone", "*", "body", "bindpos", "bindquat", "vertid", "vertweight"}, {">"}, {">"}, - {"contact", "*", "0"}, + {"contact", "*"}, {"<"}, - {"pair", "*", "11", "name", "class", "geom1", "geom2", "condim", "friction", + {"pair", "*", "name", "class", "geom1", "geom2", "condim", "friction", "solref", "solreffriction", "solimp", "gap", "margin"}, - {"exclude", "*", "3", "name", "body1", "body2"}, + {"exclude", "*", "name", "body1", "body2"}, {">"}, - {"equality", "*", "0"}, + {"equality", "*"}, {"<"}, - {"connect", "*", "10", "name", "class", "body1", "body2", "anchor", + {"connect", "*", "name", "class", "body1", "body2", "anchor", "site1", "site2", "active", "solref", "solimp"}, - {"weld", "*", "12", "name", "class", "body1", "body2", "relpose", "anchor", + {"weld", "*", "name", "class", "body1", "body2", "relpose", "anchor", "site1", "site2", "active", "solref", "solimp", "torquescale"}, - {"joint", "*", "8", "name", "class", "joint1", "joint2", "polycoef", + {"joint", "*", "name", "class", "joint1", "joint2", "polycoef", "active", "solref", "solimp"}, - {"tendon", "*", "8", "name", "class", "tendon1", "tendon2", "polycoef", + {"tendon", "*", "name", "class", "tendon1", "tendon2", "polycoef", "active", "solref", "solimp"}, - {"flex", "*", "6", "name", "class", "flex", + {"flex", "*", "name", "class", "flex", "active", "solref", "solimp"}, {">"}, - {"tendon", "*", "0"}, + {"tendon", "*"}, {"<"}, - {"spatial", "*", "21", "name", "class", "group", "limited", "actuatorfrclimited", "range", + {"spatial", "*", "name", "class", "group", "limited", "actuatorfrclimited", "range", "actuatorfrcrange", "solreflimit", "solimplimit", "solreffriction", "solimpfriction", "frictionloss", "springlength", "width", "material", "margin", "stiffness", "damping", "armature", "rgba", "user"}, {"<"}, - {"site", "*", "1", "site"}, - {"geom", "*", "2", "geom", "sidesite"}, - {"pulley", "*", "1", "divisor"}, + {"site", "*", "site"}, + {"geom", "*", "geom", "sidesite"}, + {"pulley", "*", "divisor"}, {">"}, - {"fixed", "*", "18", "name", "class", "group", "limited", "actuatorfrclimited", "range", + {"fixed", "*", "name", "class", "group", "limited", "actuatorfrclimited", "range", "actuatorfrcrange","solreflimit", "solimplimit", "solreffriction", "solimpfriction", "frictionloss", "springlength", "margin", "stiffness", "damping", "armature", "user"}, {"<"}, - {"joint", "*", "2", "joint", "coef"}, + {"joint", "*", "joint", "coef"}, {">"}, {">"}, - {"actuator", "*", "0"}, + {"actuator", "*"}, {"<"}, - {"general", "*", "29", "name", "class", "group", + {"general", "*", "name", "class", "group", "ctrllimited", "forcelimited", "actlimited", "ctrlrange", "forcerange", "actrange", "lengthrange", "gear", "cranklength", "user", "joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite", "body", "actdim", "dyntype", "gaintype", "biastype", "dynprm", "gainprm", "biasprm", "actearly"}, - {"motor", "*", "18", "name", "class", "group", + {"motor", "*", "name", "class", "group", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", "lengthrange", "gear", "cranklength", "user", "joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite"}, - {"position", "*", "23", "name", "class", "group", + {"position", "*", "name", "class", "group", "ctrllimited", "forcelimited", "ctrlrange", "inheritrange", "forcerange", "lengthrange", "gear", "cranklength", "user", "joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite", "kp", "kv", "dampratio", "timeconst"}, - {"velocity", "*", "19", "name", "class", "group", + {"velocity", "*", "name", "class", "group", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", "lengthrange", "gear", "cranklength", "user", "joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite", "kv"}, - {"intvelocity", "*", "23", "name", "class", "group", + {"intvelocity", "*", "name", "class", "group", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", "actrange", "inheritrange", "lengthrange", "gear", "cranklength", "user", "joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite", "kp", "kv", "dampratio"}, - {"damper", "*", "18", "name", "class", "group", + {"damper", "*", "name", "class", "group", "forcelimited", "ctrlrange", "forcerange", "lengthrange", "gear", "cranklength", "user", "joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite", "kv"}, - {"cylinder", "*", "22", "name", "class", "group", + {"cylinder", "*", "name", "class", "group", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", "lengthrange", "gear", "cranklength", "user", "joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite", "timeconst", "area", "diameter", "bias"}, - {"muscle", "*", "26", "name", "class", "group", + {"muscle", "*", "name", "class", "group", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", "lengthrange", "gear", "cranklength", "user", "joint", "jointinparent", "tendon", "slidersite", "cranksite", "timeconst", "tausmooth", "range", "force", "scale", "lmin", "lmax", "vmax", "fpmax", "fvmax"}, - {"adhesion", "*", "9", "name", "class", "group", + {"adhesion", "*", "name", "class", "group", "forcelimited", "ctrlrange", "forcerange", "user", "body", "gain"}, - {"plugin", "*", "25", "name", "class", "plugin", "instance", "group", + {"plugin", "*", "name", "class", "plugin", "instance", "group", "ctrllimited", "forcelimited", "actlimited", "ctrlrange", "forcerange", "actrange", "lengthrange", "gear", "cranklength", "joint", "jointinparent", "site", "actdim", "dyntype", "dynprm", "tendon", "cranksite", "slidersite", "user", "actearly"}, {"<"}, - {"config", "*", "2", "key", "value"}, + {"config", "*", "key", "value"}, {">"}, {">"}, - {"sensor", "*", "0"}, + {"sensor", "*"}, {"<"}, - {"touch", "*", "5", "name", "site", "cutoff", "noise", "user"}, - {"accelerometer", "*", "5", "name", "site", "cutoff", "noise", "user"}, - {"velocimeter", "*", "5", "name", "site", "cutoff", "noise", "user"}, - {"gyro", "*", "5", "name", "site", "cutoff", "noise", "user"}, - {"force", "*", "5", "name", "site", "cutoff", "noise", "user"}, - {"torque", "*", "5", "name", "site", "cutoff", "noise", "user"}, - {"magnetometer", "*", "5", "name", "site", "cutoff", "noise", "user"}, - {"camprojection", "*", "6", "name", "site", "camera", "cutoff", "noise", "user"}, - {"rangefinder", "*", "5", "name", "site", "cutoff", "noise", "user"}, - {"jointpos", "*", "5", "name", "joint", "cutoff", "noise", "user"}, - {"jointvel", "*", "5", "name", "joint", "cutoff", "noise", "user"}, - {"tendonpos", "*", "5", "name", "tendon", "cutoff", "noise", "user"}, - {"tendonvel", "*", "5", "name", "tendon", "cutoff", "noise", "user"}, - {"actuatorpos", "*", "5", "name", "actuator", "cutoff", "noise", "user"}, - {"actuatorvel", "*", "5", "name", "actuator", "cutoff", "noise", "user"}, - {"actuatorfrc", "*", "5", "name", "actuator", "cutoff", "noise", "user"}, - {"jointactuatorfrc", "*", "5", "name", "joint", "cutoff", "noise", "user"}, - {"tendonactuatorfrc", "*", "5", "name", "tendon", "cutoff", "noise", "user"}, - {"ballquat", "*", "5", "name", "joint", "cutoff", "noise", "user"}, - {"ballangvel", "*", "5", "name", "joint", "cutoff", "noise", "user"}, - {"jointlimitpos", "*", "5", "name", "joint", "cutoff", "noise", "user"}, - {"jointlimitvel", "*", "5", "name", "joint", "cutoff", "noise", "user"}, - {"jointlimitfrc", "*", "5", "name", "joint", "cutoff", "noise", "user"}, - {"tendonlimitpos", "*", "5", "name", "tendon", "cutoff", "noise", "user"}, - {"tendonlimitvel", "*", "5", "name", "tendon", "cutoff", "noise", "user"}, - {"tendonlimitfrc", "*", "5", "name", "tendon", "cutoff", "noise", "user"}, - {"framepos", "*", "8", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, - {"framequat", "*", "8", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, - {"framexaxis", "*", "8", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, - {"frameyaxis", "*", "8", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, - {"framezaxis", "*", "8", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, - {"framelinvel", "*", "8", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, - {"frameangvel", "*", "8", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, - {"framelinacc", "*", "6", "name", "objtype", "objname", "cutoff", "noise", "user"}, - {"frameangacc", "*", "6", "name", "objtype", "objname", "cutoff", "noise", "user"}, - {"subtreecom", "*", "5", "name", "body", "cutoff", "noise", "user"}, - {"subtreelinvel", "*", "5", "name", "body", "cutoff", "noise", "user"}, - {"subtreeangmom", "*", "5", "name", "body", "cutoff", "noise", "user"}, - {"insidesite", "*", "7", "name", "site", "objtype", "objname", "cutoff", "noise", "user"}, - {"distance", "*", "8", "name", "geom1", "geom2", "body1", "body2", "cutoff", "noise", "user"}, - {"normal", "*", "8", "name", "geom1", "geom2", "body1", "body2", "cutoff", "noise", "user"}, - {"fromto", "*", "8", "name", "geom1", "geom2", "body1", "body2", "cutoff", "noise", "user"}, - {"contact", "*", "14", "name", "geom1", "geom2", "body1", "body2", "subtree1", "subtree2", "site", + {"touch", "*", "name", "site", "cutoff", "noise", "user"}, + {"accelerometer", "*", "name", "site", "cutoff", "noise", "user"}, + {"velocimeter", "*", "name", "site", "cutoff", "noise", "user"}, + {"gyro", "*", "name", "site", "cutoff", "noise", "user"}, + {"force", "*", "name", "site", "cutoff", "noise", "user"}, + {"torque", "*", "name", "site", "cutoff", "noise", "user"}, + {"magnetometer", "*", "name", "site", "cutoff", "noise", "user"}, + {"camprojection", "*", "name", "site", "camera", "cutoff", "noise", "user"}, + {"rangefinder", "*", "name", "site", "cutoff", "noise", "user"}, + {"jointpos", "*", "name", "joint", "cutoff", "noise", "user"}, + {"jointvel", "*", "name", "joint", "cutoff", "noise", "user"}, + {"tendonpos", "*", "name", "tendon", "cutoff", "noise", "user"}, + {"tendonvel", "*", "name", "tendon", "cutoff", "noise", "user"}, + {"actuatorpos", "*", "name", "actuator", "cutoff", "noise", "user"}, + {"actuatorvel", "*", "name", "actuator", "cutoff", "noise", "user"}, + {"actuatorfrc", "*", "name", "actuator", "cutoff", "noise", "user"}, + {"jointactuatorfrc", "*", "name", "joint", "cutoff", "noise", "user"}, + {"tendonactuatorfrc", "*", "name", "tendon", "cutoff", "noise", "user"}, + {"ballquat", "*", "name", "joint", "cutoff", "noise", "user"}, + {"ballangvel", "*", "name", "joint", "cutoff", "noise", "user"}, + {"jointlimitpos", "*", "name", "joint", "cutoff", "noise", "user"}, + {"jointlimitvel", "*", "name", "joint", "cutoff", "noise", "user"}, + {"jointlimitfrc", "*", "name", "joint", "cutoff", "noise", "user"}, + {"tendonlimitpos", "*", "name", "tendon", "cutoff", "noise", "user"}, + {"tendonlimitvel", "*", "name", "tendon", "cutoff", "noise", "user"}, + {"tendonlimitfrc", "*", "name", "tendon", "cutoff", "noise", "user"}, + {"framepos", "*", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, + {"framequat", "*", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, + {"framexaxis", "*", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, + {"frameyaxis", "*", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, + {"framezaxis", "*", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, + {"framelinvel", "*", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, + {"frameangvel", "*", "name", "objtype", "objname", "reftype", "refname", "cutoff", "noise", "user"}, + {"framelinacc", "*", "name", "objtype", "objname", "cutoff", "noise", "user"}, + {"frameangacc", "*", "name", "objtype", "objname", "cutoff", "noise", "user"}, + {"subtreecom", "*", "name", "body", "cutoff", "noise", "user"}, + {"subtreelinvel", "*", "name", "body", "cutoff", "noise", "user"}, + {"subtreeangmom", "*", "name", "body", "cutoff", "noise", "user"}, + {"insidesite", "*", "name", "site", "objtype", "objname", "cutoff", "noise", "user"}, + {"distance", "*", "name", "geom1", "geom2", "body1", "body2", "cutoff", "noise", "user"}, + {"normal", "*", "name", "geom1", "geom2", "body1", "body2", "cutoff", "noise", "user"}, + {"fromto", "*", "name", "geom1", "geom2", "body1", "body2", "cutoff", "noise", "user"}, + {"contact", "*", "name", "geom1", "geom2", "body1", "body2", "subtree1", "subtree2", "site", "num", "data", "reduce", "cutoff", "noise", "user"}, - {"e_potential", "*", "4", "name", "cutoff", "noise", "user"}, - {"e_kinetic", "*", "4", "name", "cutoff", "noise", "user"}, - {"clock", "*", "4", "name", "cutoff", "noise", "user"}, - {"user", "*", "9", "name", "objtype", "objname", "datatype", "needstage", + {"e_potential", "*", "name", "cutoff", "noise", "user"}, + {"e_kinetic", "*", "name", "cutoff", "noise", "user"}, + {"clock", "*", "name", "cutoff", "noise", "user"}, + {"user", "*", "name", "objtype", "objname", "datatype", "needstage", "dim", "cutoff", "noise", "user"}, - {"tactile", "*", "4", "name", "geom", "mesh", "user"}, - {"plugin", "*", "9", "name", "plugin", "instance", "cutoff", "objtype", "objname", "reftype", "refname", + {"tactile", "*", "name", "geom", "mesh", "user"}, + {"plugin", "*", "name", "plugin", "instance", "cutoff", "objtype", "objname", "reftype", "refname", "user"}, {"<"}, - {"config", "*", "2", "key", "value"}, + {"config", "*", "key", "value"}, {">"}, {">"}, - {"keyframe", "*", "0"}, + {"keyframe", "*"}, {"<"}, - {"key", "*", "8", "name", "time", "qpos", "qvel", "act", "mpos", "mquat", "ctrl"}, + {"key", "*", "name", "time", "qpos", "qvel", "act", "mpos", "mquat", "ctrl"}, {">"}, {">"} }; diff --git a/src/xml/xml_native_reader.h b/src/xml/xml_native_reader.h index 7613cca5..51f8bf4d 100644 --- a/src/xml/xml_native_reader.h +++ b/src/xml/xml_native_reader.h @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -102,6 +103,6 @@ class mjXReader : public mjXBase { // MJCF schema #define nMJCF 241 -extern const char* MJCF[nMJCF][mjXATTRNUM]; +extern std::vector MJCF[nMJCF]; #endif // MUJOCO_SRC_XML_XML_NATIVE_READER_H_ diff --git a/src/xml/xml_util.cc b/src/xml/xml_util.cc index cb08a494..b224a372 100644 --- a/src/xml/xml_util.cc +++ b/src/xml/xml_util.cc @@ -321,15 +321,15 @@ XMLElement* NextSiblingElement(XMLElement* e, const char* name) { } // constructor -mjXSchema::mjXSchema(const char* schema[][mjXATTRNUM], unsigned nrow) { +mjXSchema::mjXSchema(std::vector schema[], unsigned nrow) { // set name and type name_ = schema[0][0]; type_ = schema[0][1][0]; // set attributes - int nattr = atoi(schema[0][2]); + int nattr = schema[0].size() - 2; for (int i = 0; i < nattr; i++) { - attr_.emplace(schema[0][3 + i]); + attr_.emplace(schema[0][2 + i]); } // process sub-elements of complex element diff --git a/src/xml/xml_util.h b/src/xml/xml_util.h index b0e38c4c..6712ded5 100644 --- a/src/xml/xml_util.h +++ b/src/xml/xml_util.h @@ -49,14 +49,10 @@ class [[nodiscard]] mjXError { }; -// max number of attribute fields in schema (plus 3) -#define mjXATTRNUM 36 - - // Custom XML file validation class mjXSchema { public: - mjXSchema(const char* schema[][mjXATTRNUM], unsigned nrow); + mjXSchema(std::vector schema[], unsigned nrow); std::string GetError(); // return error void Print(std::stringstream& str, int level) const; // print schema diff --git a/test/xml/xml_schema_test.cc b/test/xml/xml_schema_test.cc index 6b92747e..fad5924f 100644 --- a/test/xml/xml_schema_test.cc +++ b/test/xml/xml_schema_test.cc @@ -14,12 +14,11 @@ #include #include +#include #include #include "src/xml/xml_native_reader.h" -#include "src/xml/xml_util.h" #include "test/fixture.h" -#include #include namespace mujoco { @@ -29,7 +28,7 @@ namespace { using XMLSchemaTest = MujocoTest; static std::optional IsValidSchemaFormat( - const char* schema[][mjXATTRNUM], unsigned nrow) { + std::vector schema[], unsigned nrow) { if (schema[0][0][0] == '<' || schema[0][0][0] == '>') { return "expected element, found bracket"; } @@ -43,8 +42,8 @@ static std::optional IsValidSchemaFormat( // detect element if (schema[i][0][0] != '<' && schema[i][0][0] != '>') { - // first 3 pointers required - if (!schema[i][1] || !schema[i][2]) { + // first 2 pointers required + if (!schema[i][1]) { return absl::StrFormat("expected element, found null pointers" "in row %d, element %s", i, schema[i][0]); } @@ -56,19 +55,9 @@ static std::optional IsValidSchemaFormat( i, schema[i][0]); } - // number of attributes - int nattr = 0; - if (!absl::SimpleAtoi(schema[i][2], &nattr)) { - return absl::StrFormat("unparseable number of attributes in" - " row %d, element %s", i, schema[i][0]); - } else if (nattr < 0 || nattr > mjXATTRNUM - 3) { - return absl::StrFormat("invalid number of attributes in" - " row %d, element %s", i, schema[i][0]); - } - // attribute pointers - for (int j = 0; j < nattr; j++) { - if (!schema[i][3 + j]) { + for (int j = 0; j < schema[i].size() - 2; j++) { + if (!schema[i][2 + j]) { return absl::StrFormat("null attribute %d in" " row %d, element %s", j, i, schema[i][0]); }