More schema-related cleanup.

- Declare every nonzero default; make the defaults cross-check total.
- Skip default-valued attributes in the hand-written writer paths.
- Fix type facts on hand-read elements, found by the dm_control diff.

PiperOrigin-RevId: 958999733
Change-Id: I3064ccc6ae1f049c20f273abc234cd02990a8b7e
This commit is contained in:
Yuval Tassa
2026-08-04 07:04:38 -07:00
committed by Copybara-Service
parent 10793e539e
commit 574b6bd6bf
8 changed files with 885 additions and 469 deletions
+56 -17
View File
@@ -57,12 +57,14 @@ _HEADER = '''\
// 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.
// One row per bound numeric schema attribute -- total coverage, whether or
// not a default is declared. SchemaDefaultsTest compares every row against a
// freshly-constructed spec: declared values must match the C
// default-constructors, values beyond ndecl must be zero, and rows marked
// unset must hold the mjNAN sentinel. A nonzero constructor default with no
// schema declaration is therefore a test failure: the schema cannot silently
// under-declare. Rows are {attr, offset, kind, len, ndecl, unset, values};
// kind: 0=double 1=float 2=int 3=byte 4=mjtNum.
// clang-format off
struct mjXDefaultEntry {
@@ -71,6 +73,7 @@ struct mjXDefaultEntry {
int kind;
int len;
int ndecl;
int unset;
double value[8];
};
@@ -95,8 +98,28 @@ def _values(schema, attr):
return len(values), [repr(v) for v in values]
# fields whose constructor default is the mjNAN "unset" sentinel, not a value;
# the schema deliberately declares no default and the test asserts the NaN
UNSET_SENTINELS = {
('mjsBody', 'ipos'), ('mjsBody', 'fullinertia'),
('mjsGeom', 'mass'), ('mjsGeom', 'fromto'),
('mjsSite', 'fromto'),
('mjStatistic', 'meaninertia'), ('mjStatistic', 'meanmass'),
('mjStatistic', 'meansize'), ('mjStatistic', 'extent'),
('mjStatistic', 'center'),
}
def collect(schema, structs):
"""struct key -> list of row tuples, deduplicated across elements."""
"""struct key -> list of row tuples, deduplicated across elements.
Emits a row for every bound numeric attribute. An attribute with a declared
default contributes its values; an undeclared one contributes an all-zero
expectation (or the unset flag for UNSET_SENTINELS), so the test enforces
that every nonzero constructor default is declared in the schema. A declared
row replaces an undeclared row for the same field; two declared rows must
agree.
"""
tables = {}
seen = {}
for element in schema.elements.values():
@@ -109,35 +132,51 @@ def collect(schema, structs):
continue
prefix = f'{sub}.' if sub else ''
for attr in schema.expanded_attrs(element):
if attr.default is None or attr.type in ('string', 'file', 'chars',
'ref', 'id', 'flags'):
if attr.type in ('string', 'file', 'chars', 'ref', 'id', 'flags'):
continue
field = attr.facets.get('field', attr.name)
entry = fields.get(field)
if entry is None:
if 'reading' in attr.facets:
if 'reading' in attr.facets or attr.default is None:
continue # custom lowering with no direct binding
raise ValueError(f'{element.name}.{attr.name}: no field '
f'{element.spec}.{field}')
ctype, dim = entry
if ctype not in KIND_BY_CTYPE and not ctype.startswith('mjt'):
if attr.default is None:
continue # not a numeric field: nothing to compare
raise ValueError(f'{element.name}.{attr.name}: default bound to '
f'field {field} ({ctype})')
if ctype.endswith('*'):
continue # vector pointers have no in-place default
kind = KIND_BY_CTYPE.get(ctype, 2) # other mjt enums are int-sized
length = dim if dim is not None else '1'
ndecl, values = _values(schema, attr)
unset = 1 if (key, field) in UNSET_SENTINELS else 0
if attr.default is None:
ndecl, values = 0, []
else:
if unset:
raise ValueError(f'{element.name}.{attr.name}: declared default '
'on an unset-sentinel field')
ndecl, values = _values(schema, attr)
if ndecl > 8:
raise ValueError(f'{element.name}.{attr.name}: {ndecl} default '
'values exceed the row capacity')
row = (attr.name, f'(int)offsetof({element.spec}, {prefix}{field})',
kind, str(length), ndecl, values)
kind, str(length), ndecl, unset, values)
prior = seen.get((key, field))
if prior is not None:
if prior != (ndecl, values):
prior_row, prior_declared = prior
declared = attr.default is not None
if declared and prior_declared and prior_row[4:] != row[4:]:
raise ValueError(f'{element.name}.{attr.name}: conflicting '
f'defaults for {key}.{field}')
if not declared or prior_declared:
continue # keep the existing (declared or equivalent) row
tables[key][tables[key].index(prior_row)] = row
seen[(key, field)] = (row, True)
continue
seen[(key, field)] = (ndecl, values)
seen[(key, field)] = (row, attr.default is not None)
tables.setdefault(key, []).append(row)
return tables
@@ -152,9 +191,9 @@ def generate() -> str:
for key in sorted(tables):
array = 'kDefaults_' + key.replace('.', '_')
out.append(f'static const mjXDefaultEntry {array}[] = {{')
for attr, offset, kind, length, ndecl, values in tables[key]:
vals = ', '.join(values)
out.append(f' {{"{attr}", {offset}, {kind}, {length}, {ndecl}, '
for attr, offset, kind, length, ndecl, unset, values in tables[key]:
vals = ', '.join(values) if values else '0'
out.append(f' {{"{attr}", {offset}, {kind}, {length}, {ndecl}, {unset}, '
f'{{{vals}}}}},')
out.append('};')
out.append('')
+165 -155
View File
@@ -625,6 +625,16 @@
<xs:list itemType="xs:float"/>
</xs:simpleType>
<xs:simpleType name="int1to3">
<xs:restriction>
<xs:simpleType>
<xs:list itemType="xs:int"/>
</xs:simpleType>
<xs:minLength value="1"/>
<xs:maxLength value="3"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="int2">
<xs:restriction>
<xs:simpleType>
@@ -682,10 +692,10 @@
<xs:element name="lengthrange" type="lengthrange"/>
<xs:element name="include" type="include"/>
</xs:choice>
<xs:attribute name="autolimits" type="kw_bool"/>
<xs:attribute name="autolimits" type="kw_bool" default="true"/>
<xs:attribute name="boundmass" type="xs:double"/>
<xs:attribute name="boundinertia" type="xs:double"/>
<xs:attribute name="settotalmass" type="xs:double"/>
<xs:attribute name="settotalmass" type="xs:double" default="-1"/>
<xs:attribute name="balanceinertia" type="kw_bool"/>
<xs:attribute name="strippath" type="kw_bool">
<xs:annotation>
@@ -697,7 +707,7 @@
<xs:documentation>deprecation error</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="angle" type="kw_angle"/>
<xs:attribute name="angle" type="kw_angle" default="degree"/>
<xs:attribute name="fitaabb" type="kw_bool"/>
<xs:attribute name="eulerseq">
<xs:simpleType>
@@ -709,10 +719,10 @@
<xs:attribute name="meshdir" type="xs:string"/>
<xs:attribute name="texturedir" type="xs:string"/>
<xs:attribute name="discardvisual" type="kw_bool"/>
<xs:attribute name="usethread" type="kw_bool"/>
<xs:attribute name="usethread" type="kw_bool" default="true"/>
<xs:attribute name="fusestatic" type="kw_bool"/>
<xs:attribute name="inertiafromgeom" type="kw_FalseTrueAuto"/>
<xs:attribute name="inertiagrouprange" type="int2"/>
<xs:attribute name="inertiafromgeom" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="inertiagrouprange" type="int2" default="0 5"/>
<xs:attribute name="saveinertial" type="kw_bool"/>
<xs:attribute name="assetdir" type="xs:string">
<xs:annotation>
@@ -744,8 +754,8 @@
<xs:attribute name="density" type="xs:double"/>
<xs:attribute name="viscosity" type="xs:double"/>
<xs:attribute name="o_margin" type="xs:double"/>
<xs:attribute name="o_solref" type="double1to2"/>
<xs:attribute name="o_solimp" type="double1to5"/>
<xs:attribute name="o_solref" type="double1to2" default="0.02 1"/>
<xs:attribute name="o_solimp" type="double1to5" default="0.9 0.95 0.001 0.5 2"/>
<xs:attribute name="o_friction" type="double1to5" default="1 1 0.005 0.0001 0.0001"/>
<xs:attribute name="integrator" type="kw_integrator" default="Euler"/>
<xs:attribute name="cone" type="kw_cone" default="pyramidal"/>
@@ -774,17 +784,17 @@
<xs:documentation>suffixed byte count</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="njmax" type="xs:int">
<xs:attribute name="njmax" type="xs:int" default="-1">
<xs:annotation>
<xs:documentation>range/exclusivity checks</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="nconmax" type="xs:int">
<xs:attribute name="nconmax" type="xs:int" default="-1">
<xs:annotation>
<xs:documentation>range check</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="nstack" type="xs:int">
<xs:attribute name="nstack" type="xs:int" default="-1">
<xs:annotation>
<xs:documentation>range/exclusivity checks</xs:documentation>
</xs:annotation>
@@ -803,56 +813,56 @@
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nuser_body">
<xs:attribute name="nuser_body" default="-1">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:minInclusive value="-1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nuser_jnt">
<xs:attribute name="nuser_jnt" default="-1">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:minInclusive value="-1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nuser_geom">
<xs:attribute name="nuser_geom" default="-1">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:minInclusive value="-1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nuser_site">
<xs:attribute name="nuser_site" default="-1">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:minInclusive value="-1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nuser_cam">
<xs:attribute name="nuser_cam" default="-1">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:minInclusive value="-1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nuser_tendon">
<xs:attribute name="nuser_tendon" default="-1">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:minInclusive value="-1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nuser_actuator">
<xs:attribute name="nuser_actuator" default="-1">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:minInclusive value="-1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nuser_sensor">
<xs:attribute name="nuser_sensor" default="-1">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:minInclusive value="-1"/>
@@ -1123,16 +1133,16 @@
</xs:complexType>
<xs:complexType name="lengthrange">
<xs:attribute name="mode" type="kw_lrmode"/>
<xs:attribute name="useexisting" type="kw_bool"/>
<xs:attribute name="mode" type="kw_lrmode" default="muscle"/>
<xs:attribute name="useexisting" type="kw_bool" default="true"/>
<xs:attribute name="uselimit" type="kw_bool"/>
<xs:attribute name="accel" type="xs:double"/>
<xs:attribute name="accel" type="xs:double" default="20"/>
<xs:attribute name="maxforce" type="xs:double"/>
<xs:attribute name="timeconst" type="xs:double"/>
<xs:attribute name="timestep" type="xs:double"/>
<xs:attribute name="inttotal" type="xs:double"/>
<xs:attribute name="interval" type="xs:double"/>
<xs:attribute name="tolrange" type="xs:double"/>
<xs:attribute name="timeconst" type="xs:double" default="1"/>
<xs:attribute name="timestep" type="xs:double" default="0.01"/>
<xs:attribute name="inttotal" type="xs:double" default="10"/>
<xs:attribute name="interval" type="xs:double" default="2"/>
<xs:attribute name="tolrange" type="xs:double" default="0.05"/>
</xs:complexType>
<xs:complexType name="flag">
@@ -1244,31 +1254,31 @@
</xs:complexType>
<xs:complexType name="rgba">
<xs:attribute name="fog" type="float4"/>
<xs:attribute name="haze" type="float4"/>
<xs:attribute name="force" type="float4"/>
<xs:attribute name="inertia" type="float4"/>
<xs:attribute name="joint" type="float4"/>
<xs:attribute name="actuator" type="float4"/>
<xs:attribute name="actuatornegative" type="float4"/>
<xs:attribute name="actuatorpositive" type="float4"/>
<xs:attribute name="com" type="float4"/>
<xs:attribute name="camera" type="float4"/>
<xs:attribute name="light" type="float4"/>
<xs:attribute name="selectpoint" type="float4"/>
<xs:attribute name="connect" type="float4"/>
<xs:attribute name="contactpoint" type="float4"/>
<xs:attribute name="contactforce" type="float4"/>
<xs:attribute name="contactfriction" type="float4"/>
<xs:attribute name="contacttorque" type="float4"/>
<xs:attribute name="contactgap" type="float4"/>
<xs:attribute name="rangefinder" type="float4"/>
<xs:attribute name="constraint" type="float4"/>
<xs:attribute name="slidercrank" type="float4"/>
<xs:attribute name="crankbroken" type="float4"/>
<xs:attribute name="frustum" type="float4"/>
<xs:attribute name="bv" type="float4"/>
<xs:attribute name="bvactive" type="float4"/>
<xs:attribute name="fog" type="float4" default="0 0 0 1"/>
<xs:attribute name="haze" type="float4" default="1 1 1 1"/>
<xs:attribute name="force" type="float4" default="1 0.5 0.5 1"/>
<xs:attribute name="inertia" type="float4" default="0.8 0.2 0.2 0.6"/>
<xs:attribute name="joint" type="float4" default="0.2 0.6 0.8 1"/>
<xs:attribute name="actuator" type="float4" default="0.2 0.25 0.2 1"/>
<xs:attribute name="actuatornegative" type="float4" default="0.2 0.6 0.9 1"/>
<xs:attribute name="actuatorpositive" type="float4" default="0.9 0.4 0.2 1"/>
<xs:attribute name="com" type="float4" default="0.9 0.9 0.9 1"/>
<xs:attribute name="camera" type="float4" default="0.6 0.9 0.6 1"/>
<xs:attribute name="light" type="float4" default="0.6 0.6 0.9 1"/>
<xs:attribute name="selectpoint" type="float4" default="0.9 0.9 0.1 1"/>
<xs:attribute name="connect" type="float4" default="0.2 0.2 0.8 1"/>
<xs:attribute name="contactpoint" type="float4" default="0.9 0.6 0.2 1"/>
<xs:attribute name="contactforce" type="float4" default="0.7 0.9 0.9 1"/>
<xs:attribute name="contactfriction" type="float4" default="0.9 0.8 0.4 1"/>
<xs:attribute name="contacttorque" type="float4" default="0.9 0.7 0.9 1"/>
<xs:attribute name="contactgap" type="float4" default="0.5 0.8 0.9 1"/>
<xs:attribute name="rangefinder" type="float4" default="1 1 0.1 1"/>
<xs:attribute name="constraint" type="float4" default="0.9 0 0 1"/>
<xs:attribute name="slidercrank" type="float4" default="0.5 0.3 0.8 1"/>
<xs:attribute name="crankbroken" type="float4" default="0.9 0 0 1"/>
<xs:attribute name="frustum" type="float4" default="1 1 0 0.2"/>
<xs:attribute name="bv" type="float4" default="0 1 0 0.5"/>
<xs:attribute name="bvactive" type="float4" default="1 0 0 0.5"/>
</xs:complexType>
<xs:complexType name="default_mesh">
@@ -1320,20 +1330,20 @@
<xs:documentation>compile directive: saved as stiffness/damping</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="limited" type="kw_FalseTrueAuto">
<xs:attribute name="limited" type="kw_FalseTrueAuto" default="auto">
<xs:annotation>
<xs:documentation>saved unless free</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="actuatorfrclimited" type="kw_FalseTrueAuto">
<xs:attribute name="actuatorfrclimited" type="kw_FalseTrueAuto" default="auto">
<xs:annotation>
<xs:documentation>saved for slide/hinge</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="solreflimit" type="double1to2"/>
<xs:attribute name="solimplimit" type="double1to5"/>
<xs:attribute name="solreffriction" type="double1to2"/>
<xs:attribute name="solimpfriction" type="double1to5"/>
<xs:attribute name="solreflimit" type="double1to2" default="0.02 1"/>
<xs:attribute name="solimplimit" type="double1to5" default="0.9 0.95 0.001 0.5 2"/>
<xs:attribute name="solreffriction" type="double1to2" default="0.02 1"/>
<xs:attribute name="solimpfriction" type="double1to5" default="0.9 0.95 0.001 0.5 2"/>
<xs:attribute name="stiffness" type="double1to3">
<xs:annotation>
<xs:documentation>spring polynomial, 1+mjNPOLY coefficients</xs:documentation>
@@ -1414,7 +1424,7 @@
</xs:attribute>
<xs:attribute name="rgba" type="float4" default="0.5 0.5 0.5 1"/>
<xs:attribute name="fluidshape" type="kw_fluidshape"/>
<xs:attribute name="fluidcoef" type="double1to5"/>
<xs:attribute name="fluidcoef" type="double1to5" default="0.5 0.25 1.5 1 1"/>
<xs:attribute name="user" type="doublelist"/>
</xs:complexType>
@@ -1511,7 +1521,7 @@
<xs:complexType name="default_tendon">
<xs:attribute name="group" type="xs:int"/>
<xs:attribute name="limited" type="kw_FalseTrueAuto"/>
<xs:attribute name="limited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="range" type="double2"/>
<xs:attribute name="solreflimit" type="double1to2"/>
<xs:attribute name="solimplimit" type="double1to5"/>
@@ -1522,9 +1532,9 @@
<xs:attribute name="width" type="xs:double"/>
<xs:attribute name="material" type="xs:string"/>
<xs:attribute name="margin" type="xs:double"/>
<xs:attribute name="stiffness" type="xs:double"/>
<xs:attribute name="damping" type="xs:double"/>
<xs:attribute name="rgba" type="double4"/>
<xs:attribute name="stiffness" type="double1to3"/>
<xs:attribute name="damping" type="double1to3"/>
<xs:attribute name="rgba" type="float4"/>
<xs:attribute name="user" type="doublelist"/>
</xs:complexType>
@@ -1535,9 +1545,9 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="actlimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="actlimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="actrange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
@@ -1588,8 +1598,8 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
<xs:attribute name="damping" type="double1to3">
@@ -1612,8 +1622,8 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="inheritrange" type="xs:double"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
@@ -1641,8 +1651,8 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
<xs:attribute name="damping" type="double1to3">
@@ -1666,9 +1676,9 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="actlimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="actlimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="actrange" type="double2"/>
<xs:attribute name="inheritrange" type="xs:double"/>
@@ -1696,7 +1706,7 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="kp" type="xs:double"/>
<xs:attribute name="kv" type="xs:double"/>
@@ -1711,8 +1721,8 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="posrange" type="double2">
<xs:annotation>
<xs:documentation>alias: the position-setpoint range</xs:documentation>
@@ -1750,7 +1760,7 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
<xs:attribute name="damping" type="double1to3">
@@ -1774,8 +1784,8 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
<xs:attribute name="damping" type="double1to3">
@@ -1802,8 +1812,8 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
<xs:attribute name="damping" type="double1to3">
@@ -1817,7 +1827,7 @@
<xs:documentation>slidercrank-only, validated</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="timeconst" type="xs:double"/>
<xs:attribute name="timeconst" type="double2"/>
<xs:attribute name="range" type="double2"/>
<xs:attribute name="force" type="xs:double"/>
<xs:attribute name="scale" type="xs:double"/>
@@ -1835,7 +1845,7 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="gain" type="xs:double"/>
</xs:complexType>
@@ -1847,7 +1857,7 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
<xs:attribute name="damping" type="double1to3">
<xs:annotation>
@@ -2175,7 +2185,7 @@
</xs:attribute>
<xs:attribute name="rgba" type="float4" default="0.5 0.5 0.5 1"/>
<xs:attribute name="fluidshape" type="kw_fluidshape"/>
<xs:attribute name="fluidcoef" type="double1to5"/>
<xs:attribute name="fluidcoef" type="double1to5" default="0.5 0.25 1.5 1 1"/>
<xs:attribute name="user" type="doublelist"/>
</xs:complexType>
@@ -2298,7 +2308,7 @@
</xs:choice>
<xs:attribute name="prefix" type="xs:string"/>
<xs:attribute name="type" type="kw_comp" use="required"/>
<xs:attribute name="count" type="double1to3"/>
<xs:attribute name="count" type="int1to3"/>
<xs:attribute name="offset" type="double3"/>
<xs:attribute name="vertex" type="doublelist"/>
<xs:attribute name="initial" type="xs:string"/>
@@ -2324,8 +2334,8 @@
<xs:attribute name="group" type="xs:int"/>
<xs:attribute name="dim" type="xs:int"/>
<xs:attribute name="dof" type="kw_fdof"/>
<xs:attribute name="count" type="double3"/>
<xs:attribute name="cellcount" type="double3"/>
<xs:attribute name="count" type="int3"/>
<xs:attribute name="cellcount" type="int3"/>
<xs:attribute name="spacing" type="double3"/>
<xs:attribute name="radius" type="xs:double"/>
<xs:attribute name="rigid" type="kw_bool"/>
@@ -2337,7 +2347,7 @@
<xs:attribute name="element" type="doublelist"/>
<xs:attribute name="texcoord" type="doublelist"/>
<xs:attribute name="material" type="xs:string"/>
<xs:attribute name="rgba" type="double4"/>
<xs:attribute name="rgba" type="float4"/>
<xs:attribute name="flatskin" type="kw_bool"/>
<xs:attribute name="pos" type="double3"/>
<xs:attribute name="quat" type="double4"/>
@@ -2360,10 +2370,10 @@
</xs:choice>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="group" type="xs:int"/>
<xs:attribute name="dim" type="xs:int"/>
<xs:attribute name="radius" type="xs:double"/>
<xs:attribute name="dim" type="xs:int" default="2"/>
<xs:attribute name="radius" type="xs:double" default="0.005"/>
<xs:attribute name="material" type="xs:string"/>
<xs:attribute name="rgba" type="float4"/>
<xs:attribute name="rgba" type="float4" default="0.5 0.5 0.5 1"/>
<xs:attribute name="flatskin" type="kw_bool"/>
<xs:attribute name="body" type="xs:string" use="required">
<xs:annotation>
@@ -2379,9 +2389,9 @@
<xs:documentation>space-separated body names</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="cellcount" type="int3">
<xs:attribute name="cellcount" type="int3" default="1 1 1">
<xs:annotation>
<xs:documentation>seeded to {1,1,1} before reading</xs:documentation>
<xs:documentation>seeded before reading</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="dof" type="kw_fdof">
@@ -2425,14 +2435,14 @@
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="class" type="xs:string"/>
<xs:attribute name="group" type="xs:int"/>
<xs:attribute name="limited" type="kw_FalseTrueAuto"/>
<xs:attribute name="limited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="actuatorfrclimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="range" type="double2"/>
<xs:attribute name="actuatorfrcrange" type="double2"/>
<xs:attribute name="solreflimit" type="double1to2"/>
<xs:attribute name="solimplimit" type="double1to5"/>
<xs:attribute name="solreffriction" type="double1to2"/>
<xs:attribute name="solimpfriction" type="double1to5"/>
<xs:attribute name="solreflimit" type="double1to2" default="0.02 1"/>
<xs:attribute name="solimplimit" type="double1to5" default="0.9 0.95 0.001 0.5 2"/>
<xs:attribute name="solreffriction" type="double1to2" default="0.02 1"/>
<xs:attribute name="solimpfriction" type="double1to5" default="0.9 0.95 0.001 0.5 2"/>
<xs:attribute name="frictionloss" type="xs:double"/>
<xs:attribute name="springlength" type="double1to2" default="-1 -1">
<xs:annotation>
@@ -2468,14 +2478,14 @@
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="class" type="xs:string"/>
<xs:attribute name="group" type="xs:int"/>
<xs:attribute name="limited" type="kw_FalseTrueAuto"/>
<xs:attribute name="limited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="actuatorfrclimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="range" type="double2"/>
<xs:attribute name="actuatorfrcrange" type="double2"/>
<xs:attribute name="solreflimit" type="double1to2"/>
<xs:attribute name="solimplimit" type="double1to5"/>
<xs:attribute name="solreffriction" type="double1to2"/>
<xs:attribute name="solimpfriction" type="double1to5"/>
<xs:attribute name="solreflimit" type="double1to2" default="0.02 1"/>
<xs:attribute name="solimplimit" type="double1to5" default="0.9 0.95 0.001 0.5 2"/>
<xs:attribute name="solreffriction" type="double1to2" default="0.02 1"/>
<xs:attribute name="solimpfriction" type="double1to5" default="0.9 0.95 0.001 0.5 2"/>
<xs:attribute name="frictionloss" type="xs:double"/>
<xs:attribute name="springlength" type="double1to2" default="-1 -1">
<xs:annotation>
@@ -2594,9 +2604,9 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="actlimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="actlimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="actrange" type="double2"/>
<xs:attribute name="lengthrange" type="double2"/>
@@ -2662,8 +2672,8 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="lengthrange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
@@ -2696,8 +2706,8 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="inheritrange" type="xs:double"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="lengthrange" type="double2"/>
@@ -2735,8 +2745,8 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="lengthrange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
@@ -2770,9 +2780,9 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="actlimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="actlimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="actrange" type="double2"/>
<xs:attribute name="inheritrange" type="xs:double"/>
@@ -2810,7 +2820,7 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="joint" type="xs:string"/>
<xs:attribute name="site" type="xs:string"/>
@@ -2830,8 +2840,8 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="posrange" type="double2">
<xs:annotation>
<xs:documentation>alias: the position-setpoint range</xs:documentation>
@@ -2879,7 +2889,7 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="lengthrange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
@@ -2913,8 +2923,8 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="lengthrange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
@@ -2951,8 +2961,8 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="lengthrange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
@@ -2972,7 +2982,7 @@
<xs:attribute name="tendon" type="xs:string"/>
<xs:attribute name="slidersite" type="xs:string"/>
<xs:attribute name="cranksite" type="xs:string"/>
<xs:attribute name="timeconst" type="xs:double"/>
<xs:attribute name="timeconst" type="double2"/>
<xs:attribute name="tausmooth" type="xs:double"/>
<xs:attribute name="range" type="double2"/>
<xs:attribute name="force" type="xs:double"/>
@@ -2993,7 +3003,7 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="body" type="xs:string"/>
<xs:attribute name="gain" type="xs:double"/>
@@ -3008,7 +3018,7 @@
<xs:attribute name="delay" type="xs:double"/>
<xs:attribute name="ctrlrange" type="double2"/>
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="lengthrange" type="double2"/>
<xs:attribute name="gear" type="double1to6" default="1 0 0 0 0 0"/>
<xs:attribute name="damping" type="double1to3">
@@ -3059,9 +3069,9 @@
<xs:attribute name="user" type="doublelist"/>
<xs:attribute name="plugin" type="xs:string"/>
<xs:attribute name="instance" type="xs:string"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="actlimited" type="kw_FalseTrueAuto"/>
<xs:attribute name="ctrllimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcelimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="actlimited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="forcerange" type="double2"/>
<xs:attribute name="actrange" type="double2"/>
<xs:attribute name="lengthrange" type="double2"/>
@@ -3845,8 +3855,8 @@
<xs:attribute name="body" type="xs:string" use="required"/>
<xs:attribute name="bindpos" type="double3"/>
<xs:attribute name="bindquat" type="double4"/>
<xs:attribute name="vertid" type="doublelist"/>
<xs:attribute name="vertweight" type="doublelist"/>
<xs:attribute name="vertid" type="intlist"/>
<xs:attribute name="vertweight" type="floatlist"/>
</xs:complexType>
<xs:complexType name="layer">
@@ -3860,7 +3870,7 @@
<xs:documentation>constraint: at most one of: fullinertia, quat, axisangle, xyaxes, zaxis, euler</xs:documentation>
</xs:annotation>
<xs:attribute name="pos" type="double3" use="required"/>
<xs:attribute name="quat" type="double4"/>
<xs:attribute name="quat" type="double4" default="1 0 0 0"/>
<xs:attribute name="mass" type="xs:double" use="required"/>
<xs:attribute name="diaginertia" type="double3"/>
<xs:attribute name="axisangle" type="double4"/>
@@ -3890,20 +3900,20 @@
<xs:documentation>compile directive: saved as stiffness/damping</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="limited" type="kw_FalseTrueAuto">
<xs:attribute name="limited" type="kw_FalseTrueAuto" default="auto">
<xs:annotation>
<xs:documentation>saved unless free</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="actuatorfrclimited" type="kw_FalseTrueAuto">
<xs:attribute name="actuatorfrclimited" type="kw_FalseTrueAuto" default="auto">
<xs:annotation>
<xs:documentation>saved for slide/hinge</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="solreflimit" type="double1to2"/>
<xs:attribute name="solimplimit" type="double1to5"/>
<xs:attribute name="solreffriction" type="double1to2"/>
<xs:attribute name="solimpfriction" type="double1to5"/>
<xs:attribute name="solreflimit" type="double1to2" default="0.02 1"/>
<xs:attribute name="solimplimit" type="double1to5" default="0.9 0.95 0.001 0.5 2"/>
<xs:attribute name="solreffriction" type="double1to2" default="0.02 1"/>
<xs:attribute name="solimpfriction" type="double1to5" default="0.9 0.95 0.001 0.5 2"/>
<xs:attribute name="stiffness" type="double1to3">
<xs:annotation>
<xs:documentation>spring polynomial, 1+mjNPOLY coefficients</xs:documentation>
@@ -3946,7 +3956,7 @@
<xs:attribute name="solimpfix" type="double1to5"/>
<xs:attribute name="type" type="kw_jointtype"/>
<xs:attribute name="axis" type="double3"/>
<xs:attribute name="limited" type="kw_FalseTrueAuto"/>
<xs:attribute name="limited" type="kw_FalseTrueAuto" default="auto"/>
<xs:attribute name="range" type="double2"/>
<xs:attribute name="margin" type="xs:double"/>
<xs:attribute name="solreflimit" type="double1to2"/>
@@ -3960,7 +3970,7 @@
<xs:attribute name="texcoord" type="kw_bool"/>
<xs:attribute name="material" type="xs:string"/>
<xs:attribute name="group" type="xs:int"/>
<xs:attribute name="rgba" type="double4"/>
<xs:attribute name="rgba" type="float4"/>
<xs:attribute name="inflate" type="xs:double"/>
<xs:attribute name="subgrid" type="xs:int"/>
</xs:complexType>
@@ -3974,7 +3984,7 @@
<xs:attribute name="priority" type="xs:int"/>
<xs:attribute name="size" type="double1to3"/>
<xs:attribute name="material" type="xs:string"/>
<xs:attribute name="rgba" type="double4"/>
<xs:attribute name="rgba" type="float4"/>
<xs:attribute name="friction" type="double1to3"/>
<xs:attribute name="mass" type="xs:double"/>
<xs:attribute name="density" type="xs:double"/>
@@ -3991,7 +4001,7 @@
<xs:attribute name="group" type="xs:int"/>
<xs:attribute name="size" type="double1to3"/>
<xs:attribute name="material" type="xs:string"/>
<xs:attribute name="rgba" type="double4"/>
<xs:attribute name="rgba" type="float4"/>
</xs:complexType>
<xs:complexType name="flexcomp_edge">
@@ -4006,24 +4016,24 @@
<xs:attribute name="young" type="xs:double"/>
<xs:attribute name="poisson" type="xs:double"/>
<xs:attribute name="damping" type="xs:double"/>
<xs:attribute name="thickness" type="xs:double"/>
<xs:attribute name="thickness" type="xs:double" default="-1"/>
<xs:attribute name="elastic2d" type="kw_elastic2d"/>
</xs:complexType>
<xs:complexType name="flexcomp_contact">
<xs:attribute name="contype" type="xs:int"/>
<xs:attribute name="conaffinity" type="xs:int"/>
<xs:attribute name="condim" type="xs:int"/>
<xs:attribute name="contype" type="xs:int" default="1"/>
<xs:attribute name="conaffinity" type="xs:int" default="1"/>
<xs:attribute name="condim" type="xs:int" default="3"/>
<xs:attribute name="priority" type="xs:int"/>
<xs:attribute name="friction" type="double1to3"/>
<xs:attribute name="solmix" type="xs:double"/>
<xs:attribute name="solref" type="double1to2"/>
<xs:attribute name="solimp" type="double1to5"/>
<xs:attribute name="friction" type="double1to3" default="1 0.005 0.0001"/>
<xs:attribute name="solmix" type="xs:double" default="1"/>
<xs:attribute name="solref" type="double1to2" default="0.02 1"/>
<xs:attribute name="solimp" type="double1to5" default="0.9 0.95 0.001 0.5 2"/>
<xs:attribute name="margin" type="xs:double"/>
<xs:attribute name="gap" type="xs:double"/>
<xs:attribute name="internal" type="kw_bool"/>
<xs:attribute name="selfcollide" type="kw_flexself"/>
<xs:attribute name="activelayers" type="xs:int"/>
<xs:attribute name="selfcollide" type="kw_flexself" default="auto"/>
<xs:attribute name="activelayers" type="xs:int" default="1"/>
<xs:attribute name="passive" type="kw_bool"/>
</xs:complexType>
+413 -157
View File
@@ -16,12 +16,14 @@
// 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.
// One row per bound numeric schema attribute -- total coverage, whether or
// not a default is declared. SchemaDefaultsTest compares every row against a
// freshly-constructed spec: declared values must match the C
// default-constructors, values beyond ndecl must be zero, and rows marked
// unset must hold the mjNAN sentinel. A nonzero constructor default with no
// schema declaration is therefore a test failure: the schema cannot silently
// under-declare. Rows are {attr, offset, kind, len, ndecl, unset, values};
// kind: 0=double 1=float 2=int 3=byte 4=mjtNum.
// clang-format off
struct mjXDefaultEntry {
@@ -30,6 +32,7 @@ struct mjXDefaultEntry {
int kind;
int len;
int ndecl;
int unset;
double value[8];
};
@@ -40,240 +43,493 @@ struct mjXDefaultTable {
};
static const mjXDefaultEntry kDefaults_mjLROpt[] = {
{"mode", (int)offsetof(mjLROpt, mode), 2, 1, 1, 0, {(double)mjLRMODE_MUSCLE}},
{"useexisting", (int)offsetof(mjLROpt, useexisting), 2, 1, 1, 0, {1}},
{"uselimit", (int)offsetof(mjLROpt, uselimit), 2, 1, 0, 0, {0}},
{"accel", (int)offsetof(mjLROpt, accel), 4, 1, 1, 0, {20.0}},
{"maxforce", (int)offsetof(mjLROpt, maxforce), 4, 1, 0, 0, {0}},
{"timeconst", (int)offsetof(mjLROpt, timeconst), 4, 1, 1, 0, {1.0}},
{"timestep", (int)offsetof(mjLROpt, timestep), 4, 1, 1, 0, {0.01}},
{"inttotal", (int)offsetof(mjLROpt, inttotal), 4, 1, 1, 0, {10.0}},
{"interval", (int)offsetof(mjLROpt, interval), 4, 1, 1, 0, {2.0}},
{"tolrange", (int)offsetof(mjLROpt, tolrange), 4, 1, 1, 0, {0.05}},
};
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}},
{"timestep", (int)offsetof(mjOption, timestep), 4, 1, 1, 0, {0.002}},
{"impratio", (int)offsetof(mjOption, impratio), 4, 1, 1, 0, {1.0}},
{"tolerance", (int)offsetof(mjOption, tolerance), 4, 1, 1, 0, {1e-08}},
{"ls_tolerance", (int)offsetof(mjOption, ls_tolerance), 4, 1, 1, 0, {0.01}},
{"noslip_tolerance", (int)offsetof(mjOption, noslip_tolerance), 4, 1, 1, 0, {1e-06}},
{"ccd_tolerance", (int)offsetof(mjOption, ccd_tolerance), 4, 1, 1, 0, {1e-06}},
{"sleep_tolerance", (int)offsetof(mjOption, sleep_tolerance), 4, 1, 1, 0, {0.001}},
{"gravity", (int)offsetof(mjOption, gravity), 4, 3, 3, 0, {0.0, 0.0, -9.81}},
{"wind", (int)offsetof(mjOption, wind), 4, 3, 3, 0, {0.0, 0.0, 0.0}},
{"magnetic", (int)offsetof(mjOption, magnetic), 4, 3, 3, 0, {0.0, -0.5, 0.0}},
{"density", (int)offsetof(mjOption, density), 4, 1, 0, 0, {0}},
{"viscosity", (int)offsetof(mjOption, viscosity), 4, 1, 0, 0, {0}},
{"o_margin", (int)offsetof(mjOption, o_margin), 4, 1, 0, 0, {0}},
{"o_solref", (int)offsetof(mjOption, o_solref), 4, mjNREF, 2, 0, {0.02, 1.0}},
{"o_solimp", (int)offsetof(mjOption, o_solimp), 4, mjNIMP, 5, 0, {0.9, 0.95, 0.001, 0.5, 2.0}},
{"o_friction", (int)offsetof(mjOption, o_friction), 4, 5, 5, 0, {1.0, 1.0, 0.005, 0.0001, 0.0001}},
{"integrator", (int)offsetof(mjOption, integrator), 2, 1, 1, 0, {(double)mjINT_EULER}},
{"cone", (int)offsetof(mjOption, cone), 2, 1, 1, 0, {(double)mjCONE_PYRAMIDAL}},
{"jacobian", (int)offsetof(mjOption, jacobian), 2, 1, 1, 0, {(double)mjJAC_AUTO}},
{"solver", (int)offsetof(mjOption, solver), 2, 1, 1, 0, {(double)mjSOL_NEWTON}},
{"iterations", (int)offsetof(mjOption, iterations), 2, 1, 1, 0, {100.0}},
{"ls_iterations", (int)offsetof(mjOption, ls_iterations), 2, 1, 1, 0, {50.0}},
{"noslip_iterations", (int)offsetof(mjOption, noslip_iterations), 2, 1, 0, 0, {0}},
{"ccd_iterations", (int)offsetof(mjOption, ccd_iterations), 2, 1, 1, 0, {35.0}},
{"sdf_iterations", (int)offsetof(mjOption, sdf_iterations), 2, 1, 1, 0, {10.0}},
{"sdf_initpoints", (int)offsetof(mjOption, sdf_initpoints), 2, 1, 1, 0, {40.0}},
};
static const mjXDefaultEntry kDefaults_mjSpec[] = {
{"njmax", (int)offsetof(mjSpec, njmax), 2, 1, 1, 0, {-1.0}},
{"nconmax", (int)offsetof(mjSpec, nconmax), 2, 1, 1, 0, {-1.0}},
{"nstack", (int)offsetof(mjSpec, nstack), 2, 1, 1, 0, {-1.0}},
{"nuserdata", (int)offsetof(mjSpec, nuserdata), 2, 1, 0, 0, {0}},
{"nkey", (int)offsetof(mjSpec, nkey), 2, 1, 0, 0, {0}},
{"nuser_body", (int)offsetof(mjSpec, nuser_body), 2, 1, 1, 0, {-1.0}},
{"nuser_jnt", (int)offsetof(mjSpec, nuser_jnt), 2, 1, 1, 0, {-1.0}},
{"nuser_geom", (int)offsetof(mjSpec, nuser_geom), 2, 1, 1, 0, {-1.0}},
{"nuser_site", (int)offsetof(mjSpec, nuser_site), 2, 1, 1, 0, {-1.0}},
{"nuser_cam", (int)offsetof(mjSpec, nuser_cam), 2, 1, 1, 0, {-1.0}},
{"nuser_tendon", (int)offsetof(mjSpec, nuser_tendon), 2, 1, 1, 0, {-1.0}},
{"nuser_actuator", (int)offsetof(mjSpec, nuser_actuator), 2, 1, 1, 0, {-1.0}},
{"nuser_sensor", (int)offsetof(mjSpec, nuser_sensor), 2, 1, 1, 0, {-1.0}},
};
static const mjXDefaultEntry kDefaults_mjStatistic[] = {
{"meaninertia", (int)offsetof(mjStatistic, meaninertia), 4, 1, 0, 1, {0}},
{"meanmass", (int)offsetof(mjStatistic, meanmass), 4, 1, 0, 1, {0}},
{"meansize", (int)offsetof(mjStatistic, meansize), 4, 1, 0, 1, {0}},
{"extent", (int)offsetof(mjStatistic, extent), 4, 1, 0, 1, {0}},
{"center", (int)offsetof(mjStatistic, center), 4, 3, 0, 1, {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}},
{"cameraid", (int)offsetof(mjVisual, global.cameraid), 2, 1, 1, 0, {-1.0}},
{"orthographic", (int)offsetof(mjVisual, global.orthographic), 2, 1, 1, 0, {0}},
{"fovy", (int)offsetof(mjVisual, global.fovy), 1, 1, 1, 0, {45.0}},
{"ipd", (int)offsetof(mjVisual, global.ipd), 1, 1, 1, 0, {0.068}},
{"azimuth", (int)offsetof(mjVisual, global.azimuth), 1, 1, 1, 0, {90.0}},
{"elevation", (int)offsetof(mjVisual, global.elevation), 1, 1, 1, 0, {-45.0}},
{"linewidth", (int)offsetof(mjVisual, global.linewidth), 1, 1, 1, 0, {1.0}},
{"glow", (int)offsetof(mjVisual, global.glow), 1, 1, 1, 0, {0.3}},
{"offwidth", (int)offsetof(mjVisual, global.offwidth), 2, 1, 1, 0, {640.0}},
{"offheight", (int)offsetof(mjVisual, global.offheight), 2, 1, 1, 0, {480.0}},
{"realtime", (int)offsetof(mjVisual, global.realtime), 1, 1, 1, 0, {1.0}},
{"ellipsoidinertia", (int)offsetof(mjVisual, global.ellipsoidinertia), 2, 1, 1, 0, {0}},
{"bvactive", (int)offsetof(mjVisual, global.bvactive), 2, 1, 1, 0, {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}},
{"ambient", (int)offsetof(mjVisual, headlight.ambient), 1, 3, 3, 0, {0.1, 0.1, 0.1}},
{"diffuse", (int)offsetof(mjVisual, headlight.diffuse), 1, 3, 3, 0, {0.4, 0.4, 0.4}},
{"specular", (int)offsetof(mjVisual, headlight.specular), 1, 3, 3, 0, {0.5, 0.5, 0.5}},
{"active", (int)offsetof(mjVisual, headlight.active), 2, 1, 1, 0, {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}},
{"stiffness", (int)offsetof(mjVisual, map.stiffness), 1, 1, 1, 0, {100.0}},
{"stiffnessrot", (int)offsetof(mjVisual, map.stiffnessrot), 1, 1, 1, 0, {500.0}},
{"force", (int)offsetof(mjVisual, map.force), 1, 1, 1, 0, {0.005}},
{"torque", (int)offsetof(mjVisual, map.torque), 1, 1, 1, 0, {0.1}},
{"alpha", (int)offsetof(mjVisual, map.alpha), 1, 1, 1, 0, {0.3}},
{"fogstart", (int)offsetof(mjVisual, map.fogstart), 1, 1, 1, 0, {3.0}},
{"fogend", (int)offsetof(mjVisual, map.fogend), 1, 1, 1, 0, {10.0}},
{"znear", (int)offsetof(mjVisual, map.znear), 1, 1, 1, 0, {0.01}},
{"zfar", (int)offsetof(mjVisual, map.zfar), 1, 1, 1, 0, {50.0}},
{"haze", (int)offsetof(mjVisual, map.haze), 1, 1, 1, 0, {0.3}},
{"shadowclip", (int)offsetof(mjVisual, map.shadowclip), 1, 1, 1, 0, {1.0}},
{"shadowscale", (int)offsetof(mjVisual, map.shadowscale), 1, 1, 1, 0, {0.6}},
{"actuatortendon", (int)offsetof(mjVisual, map.actuatortendon), 1, 1, 1, 0, {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}},
{"shadowsize", (int)offsetof(mjVisual, quality.shadowsize), 2, 1, 1, 0, {4096.0}},
{"offsamples", (int)offsetof(mjVisual, quality.offsamples), 2, 1, 1, 0, {4.0}},
{"numslices", (int)offsetof(mjVisual, quality.numslices), 2, 1, 1, 0, {28.0}},
{"numstacks", (int)offsetof(mjVisual, quality.numstacks), 2, 1, 1, 0, {16.0}},
{"numquads", (int)offsetof(mjVisual, quality.numquads), 2, 1, 1, 0, {4.0}},
};
static const mjXDefaultEntry kDefaults_mjVisual_rgba[] = {
{"fog", (int)offsetof(mjVisual, rgba.fog), 1, 4, 4, 0, {0.0, 0.0, 0.0, 1.0}},
{"haze", (int)offsetof(mjVisual, rgba.haze), 1, 4, 4, 0, {1.0, 1.0, 1.0, 1.0}},
{"force", (int)offsetof(mjVisual, rgba.force), 1, 4, 4, 0, {1.0, 0.5, 0.5, 1.0}},
{"inertia", (int)offsetof(mjVisual, rgba.inertia), 1, 4, 4, 0, {0.8, 0.2, 0.2, 0.6}},
{"joint", (int)offsetof(mjVisual, rgba.joint), 1, 4, 4, 0, {0.2, 0.6, 0.8, 1.0}},
{"actuator", (int)offsetof(mjVisual, rgba.actuator), 1, 4, 4, 0, {0.2, 0.25, 0.2, 1.0}},
{"actuatornegative", (int)offsetof(mjVisual, rgba.actuatornegative), 1, 4, 4, 0, {0.2, 0.6, 0.9, 1.0}},
{"actuatorpositive", (int)offsetof(mjVisual, rgba.actuatorpositive), 1, 4, 4, 0, {0.9, 0.4, 0.2, 1.0}},
{"com", (int)offsetof(mjVisual, rgba.com), 1, 4, 4, 0, {0.9, 0.9, 0.9, 1.0}},
{"camera", (int)offsetof(mjVisual, rgba.camera), 1, 4, 4, 0, {0.6, 0.9, 0.6, 1.0}},
{"light", (int)offsetof(mjVisual, rgba.light), 1, 4, 4, 0, {0.6, 0.6, 0.9, 1.0}},
{"selectpoint", (int)offsetof(mjVisual, rgba.selectpoint), 1, 4, 4, 0, {0.9, 0.9, 0.1, 1.0}},
{"connect", (int)offsetof(mjVisual, rgba.connect), 1, 4, 4, 0, {0.2, 0.2, 0.8, 1.0}},
{"contactpoint", (int)offsetof(mjVisual, rgba.contactpoint), 1, 4, 4, 0, {0.9, 0.6, 0.2, 1.0}},
{"contactforce", (int)offsetof(mjVisual, rgba.contactforce), 1, 4, 4, 0, {0.7, 0.9, 0.9, 1.0}},
{"contactfriction", (int)offsetof(mjVisual, rgba.contactfriction), 1, 4, 4, 0, {0.9, 0.8, 0.4, 1.0}},
{"contacttorque", (int)offsetof(mjVisual, rgba.contacttorque), 1, 4, 4, 0, {0.9, 0.7, 0.9, 1.0}},
{"contactgap", (int)offsetof(mjVisual, rgba.contactgap), 1, 4, 4, 0, {0.5, 0.8, 0.9, 1.0}},
{"rangefinder", (int)offsetof(mjVisual, rgba.rangefinder), 1, 4, 4, 0, {1.0, 1.0, 0.1, 1.0}},
{"constraint", (int)offsetof(mjVisual, rgba.constraint), 1, 4, 4, 0, {0.9, 0.0, 0.0, 1.0}},
{"slidercrank", (int)offsetof(mjVisual, rgba.slidercrank), 1, 4, 4, 0, {0.5, 0.3, 0.8, 1.0}},
{"crankbroken", (int)offsetof(mjVisual, rgba.crankbroken), 1, 4, 4, 0, {0.9, 0.0, 0.0, 1.0}},
{"frustum", (int)offsetof(mjVisual, rgba.frustum), 1, 4, 4, 0, {1.0, 1.0, 0.0, 0.2}},
{"bv", (int)offsetof(mjVisual, rgba.bv), 1, 4, 4, 0, {0.0, 1.0, 0.0, 0.5}},
{"bvactive", (int)offsetof(mjVisual, rgba.bvactive), 1, 4, 4, 0, {1.0, 0.0, 0.0, 0.5}},
};
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}},
{"forcewidth", (int)offsetof(mjVisual, scale.forcewidth), 1, 1, 1, 0, {0.1}},
{"contactwidth", (int)offsetof(mjVisual, scale.contactwidth), 1, 1, 1, 0, {0.3}},
{"contactheight", (int)offsetof(mjVisual, scale.contactheight), 1, 1, 1, 0, {0.1}},
{"connect", (int)offsetof(mjVisual, scale.connect), 1, 1, 1, 0, {0.2}},
{"com", (int)offsetof(mjVisual, scale.com), 1, 1, 1, 0, {0.4}},
{"camera", (int)offsetof(mjVisual, scale.camera), 1, 1, 1, 0, {0.3}},
{"light", (int)offsetof(mjVisual, scale.light), 1, 1, 1, 0, {0.3}},
{"selectpoint", (int)offsetof(mjVisual, scale.selectpoint), 1, 1, 1, 0, {0.2}},
{"jointlength", (int)offsetof(mjVisual, scale.jointlength), 1, 1, 1, 0, {1.0}},
{"jointwidth", (int)offsetof(mjVisual, scale.jointwidth), 1, 1, 1, 0, {0.1}},
{"actuatorlength", (int)offsetof(mjVisual, scale.actuatorlength), 1, 1, 1, 0, {0.7}},
{"actuatorwidth", (int)offsetof(mjVisual, scale.actuatorwidth), 1, 1, 1, 0, {0.2}},
{"framelength", (int)offsetof(mjVisual, scale.framelength), 1, 1, 1, 0, {1.0}},
{"framewidth", (int)offsetof(mjVisual, scale.framewidth), 1, 1, 1, 0, {0.1}},
{"constraint", (int)offsetof(mjVisual, scale.constraint), 1, 1, 1, 0, {0.1}},
{"slidercrank", (int)offsetof(mjVisual, scale.slidercrank), 1, 1, 1, 0, {0.2}},
{"frustum", (int)offsetof(mjVisual, scale.frustum), 1, 1, 1, 0, {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}},
{"group", (int)offsetof(mjsActuator, group), 2, 1, 0, 0, {0}},
{"nsample", (int)offsetof(mjsActuator, nsample), 2, 1, 0, 0, {0}},
{"interp", (int)offsetof(mjsActuator, interp), 2, 1, 0, 0, {0}},
{"delay", (int)offsetof(mjsActuator, delay), 0, 1, 0, 0, {0}},
{"ctrlrange", (int)offsetof(mjsActuator, ctrlrange), 0, 2, 0, 0, {0}},
{"ctrllimited", (int)offsetof(mjsActuator, ctrllimited), 2, 1, 1, 0, {(double)2}},
{"forcelimited", (int)offsetof(mjsActuator, forcelimited), 2, 1, 1, 0, {(double)2}},
{"actlimited", (int)offsetof(mjsActuator, actlimited), 2, 1, 1, 0, {(double)2}},
{"forcerange", (int)offsetof(mjsActuator, forcerange), 0, 2, 0, 0, {0}},
{"actrange", (int)offsetof(mjsActuator, actrange), 0, 2, 0, 0, {0}},
{"lengthrange", (int)offsetof(mjsActuator, lengthrange), 0, 2, 0, 0, {0}},
{"gear", (int)offsetof(mjsActuator, gear), 0, 6, 6, 0, {1.0, 0.0, 0.0, 0.0, 0.0, 0.0}},
{"damping", (int)offsetof(mjsActuator, damping), 0, mjNPOLY+1, 0, 0, {0}},
{"armature", (int)offsetof(mjsActuator, armature), 0, 1, 0, 0, {0}},
{"cranklength", (int)offsetof(mjsActuator, cranklength), 0, 1, 0, 0, {0}},
{"actdim", (int)offsetof(mjsActuator, actdim), 2, 1, 1, 0, {-1.0}},
{"velrange", (int)offsetof(mjsActuator, velrange), 0, 2, 0, 0, {0}},
{"ffrange", (int)offsetof(mjsActuator, ffrange), 0, 2, 0, 0, {0}},
{"dyntype", (int)offsetof(mjsActuator, dyntype), 2, 1, 1, 0, {(double)mjDYN_NONE}},
{"gaintype", (int)offsetof(mjsActuator, gaintype), 2, 1, 1, 0, {(double)mjGAIN_FIXED}},
{"biastype", (int)offsetof(mjsActuator, biastype), 2, 1, 1, 0, {(double)mjBIAS_NONE}},
{"dynprm", (int)offsetof(mjsActuator, dynprm), 0, mjNDYN, 1, 0, {1.0}},
{"gainprm", (int)offsetof(mjsActuator, gainprm), 0, mjNGAIN, 1, 0, {1.0}},
{"biasprm", (int)offsetof(mjsActuator, biasprm), 0, mjNBIAS, 0, 0, {0}},
{"actearly", (int)offsetof(mjsActuator, actearly), 3, 1, 0, 0, {0}},
{"inheritrange", (int)offsetof(mjsActuator, inheritrange), 0, 1, 0, 0, {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}},
{"pos", (int)offsetof(mjsBody, pos), 0, 3, 3, 0, {0.0, 0.0, 0.0}},
{"quat", (int)offsetof(mjsBody, quat), 0, 4, 4, 0, {1.0, 0.0, 0.0, 0.0}},
{"mocap", (int)offsetof(mjsBody, mocap), 3, 1, 0, 0, {0}},
{"gravcomp", (int)offsetof(mjsBody, gravcomp), 0, 1, 0, 0, {0}},
{"sleep", (int)offsetof(mjsBody, sleep), 2, 1, 0, 0, {0}},
{"simple", (int)offsetof(mjsBody, simple), 3, 1, 1, 0, {(double)1}},
{"pos", (int)offsetof(mjsBody, ipos), 0, 3, 0, 1, {0}},
{"quat", (int)offsetof(mjsBody, iquat), 0, 4, 4, 0, {1.0, 0.0, 0.0, 0.0}},
{"mass", (int)offsetof(mjsBody, mass), 0, 1, 0, 0, {0}},
{"diaginertia", (int)offsetof(mjsBody, inertia), 0, 3, 0, 0, {0}},
{"fullinertia", (int)offsetof(mjsBody, fullinertia), 0, 6, 0, 1, {0}},
};
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}},
{"projection", (int)offsetof(mjsCamera, proj), 2, 1, 0, 0, {0}},
{"fovy", (int)offsetof(mjsCamera, fovy), 0, 1, 1, 0, {45.0}},
{"ipd", (int)offsetof(mjsCamera, ipd), 0, 1, 1, 0, {0.068}},
{"resolution", (int)offsetof(mjsCamera, resolution), 2, 2, 2, 0, {1.0, 1.0}},
{"pos", (int)offsetof(mjsCamera, pos), 0, 3, 3, 0, {0.0, 0.0, 0.0}},
{"quat", (int)offsetof(mjsCamera, quat), 0, 4, 4, 0, {1.0, 0.0, 0.0, 0.0}},
{"mode", (int)offsetof(mjsCamera, mode), 2, 1, 1, 0, {(double)mjCAMLIGHT_FIXED}},
{"focal", (int)offsetof(mjsCamera, focal_length), 1, 2, 0, 0, {0}},
{"focalpixel", (int)offsetof(mjsCamera, focal_pixel), 1, 2, 0, 0, {0}},
{"principal", (int)offsetof(mjsCamera, principal_length), 1, 2, 0, 0, {0}},
{"principalpixel", (int)offsetof(mjsCamera, principal_pixel), 1, 2, 0, 0, {0}},
{"sensorsize", (int)offsetof(mjsCamera, sensor_size), 1, 2, 0, 0, {0}},
};
static const mjXDefaultEntry kDefaults_mjsCompiler[] = {
{"autolimits", (int)offsetof(mjsCompiler, autolimits), 3, 1, 1, 0, {1}},
{"boundmass", (int)offsetof(mjsCompiler, boundmass), 0, 1, 0, 0, {0}},
{"boundinertia", (int)offsetof(mjsCompiler, boundinertia), 0, 1, 0, 0, {0}},
{"settotalmass", (int)offsetof(mjsCompiler, settotalmass), 0, 1, 1, 0, {-1.0}},
{"balanceinertia", (int)offsetof(mjsCompiler, balanceinertia), 3, 1, 0, 0, {0}},
{"angle", (int)offsetof(mjsCompiler, degree), 3, 1, 1, 0, {(double)1}},
{"fitaabb", (int)offsetof(mjsCompiler, fitaabb), 3, 1, 0, 0, {0}},
{"discardvisual", (int)offsetof(mjsCompiler, discardvisual), 3, 1, 0, 0, {0}},
{"usethread", (int)offsetof(mjsCompiler, usethread), 3, 1, 1, 0, {1}},
{"fusestatic", (int)offsetof(mjsCompiler, fusestatic), 3, 1, 0, 0, {0}},
{"inertiafromgeom", (int)offsetof(mjsCompiler, inertiafromgeom), 2, 1, 1, 0, {(double)2}},
{"inertiagrouprange", (int)offsetof(mjsCompiler, inertiagrouprange), 2, 2, 2, 0, {0.0, 5.0}},
{"saveinertial", (int)offsetof(mjsCompiler, saveinertial), 3, 1, 0, 0, {0}},
{"alignfree", (int)offsetof(mjsCompiler, alignfree), 3, 1, 0, 0, {0}},
{"conflict", (int)offsetof(mjsCompiler, conflict), 2, 1, 0, 0, {0}},
};
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}},
{"active", (int)offsetof(mjsEquality, active), 3, 1, 1, 0, {1}},
{"solref", (int)offsetof(mjsEquality, solref), 4, mjNREF, 2, 0, {0.02, 1.0}},
{"solimp", (int)offsetof(mjsEquality, solimp), 4, mjNIMP, 5, 0, {0.9, 0.95, 0.001, 0.5, 2.0}},
};
static const mjXDefaultEntry kDefaults_mjsFlex[] = {
{"young", (int)offsetof(mjsFlex, young), 0, 1, 0, 0, {0}},
{"poisson", (int)offsetof(mjsFlex, poisson), 0, 1, 0, 0, {0}},
{"damping", (int)offsetof(mjsFlex, damping), 0, 1, 0, 0, {0}},
{"thickness", (int)offsetof(mjsFlex, thickness), 0, 1, 1, 0, {-1.0}},
{"elastic2d", (int)offsetof(mjsFlex, elastic2d), 2, 1, 0, 0, {0}},
{"contype", (int)offsetof(mjsFlex, contype), 2, 1, 1, 0, {1.0}},
{"conaffinity", (int)offsetof(mjsFlex, conaffinity), 2, 1, 1, 0, {1.0}},
{"condim", (int)offsetof(mjsFlex, condim), 2, 1, 1, 0, {3.0}},
{"priority", (int)offsetof(mjsFlex, priority), 2, 1, 0, 0, {0}},
{"friction", (int)offsetof(mjsFlex, friction), 0, 3, 3, 0, {1.0, 0.005, 0.0001}},
{"solmix", (int)offsetof(mjsFlex, solmix), 0, 1, 1, 0, {1.0}},
{"solref", (int)offsetof(mjsFlex, solref), 4, mjNREF, 2, 0, {0.02, 1.0}},
{"solimp", (int)offsetof(mjsFlex, solimp), 4, mjNIMP, 5, 0, {0.9, 0.95, 0.001, 0.5, 2.0}},
{"margin", (int)offsetof(mjsFlex, margin), 0, 1, 0, 0, {0}},
{"gap", (int)offsetof(mjsFlex, gap), 0, 1, 0, 0, {0}},
{"internal", (int)offsetof(mjsFlex, internal), 3, 1, 0, 0, {0}},
{"selfcollide", (int)offsetof(mjsFlex, selfcollide), 2, 1, 1, 0, {(double)mjFLEXSELF_AUTO}},
{"activelayers", (int)offsetof(mjsFlex, activelayers), 2, 1, 1, 0, {1.0}},
{"passive", (int)offsetof(mjsFlex, passive), 2, 1, 0, 0, {0}},
{"group", (int)offsetof(mjsFlex, group), 2, 1, 0, 0, {0}},
{"dim", (int)offsetof(mjsFlex, dim), 2, 1, 1, 0, {2.0}},
{"radius", (int)offsetof(mjsFlex, radius), 0, 1, 1, 0, {0.005}},
{"rgba", (int)offsetof(mjsFlex, rgba), 1, 4, 4, 0, {0.5, 0.5, 0.5, 1.0}},
{"flatskin", (int)offsetof(mjsFlex, flatskin), 3, 1, 0, 0, {0}},
{"cellcount", (int)offsetof(mjsFlex, cellcount), 2, 3, 3, 0, {1.0, 1.0, 1.0}},
{"stiffness", (int)offsetof(mjsFlex, edgestiffness), 0, 1, 0, 0, {0}},
{"damping", (int)offsetof(mjsFlex, edgedamping), 0, 1, 0, 0, {0}},
};
static const mjXDefaultEntry kDefaults_mjsFrame[] = {
{"quat", (int)offsetof(mjsFrame, quat), 0, 4, 4, {1.0, 0.0, 0.0, 0.0}},
{"pos", (int)offsetof(mjsFrame, pos), 0, 3, 0, 0, {0}},
{"quat", (int)offsetof(mjsFrame, quat), 0, 4, 4, 0, {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}},
{"type", (int)offsetof(mjsGeom, type), 2, 1, 1, 0, {(double)mjGEOM_SPHERE}},
{"contype", (int)offsetof(mjsGeom, contype), 2, 1, 1, 0, {1.0}},
{"conaffinity", (int)offsetof(mjsGeom, conaffinity), 2, 1, 1, 0, {1.0}},
{"condim", (int)offsetof(mjsGeom, condim), 2, 1, 1, 0, {3.0}},
{"group", (int)offsetof(mjsGeom, group), 2, 1, 0, 0, {0}},
{"priority", (int)offsetof(mjsGeom, priority), 2, 1, 0, 0, {0}},
{"size", (int)offsetof(mjsGeom, size), 0, 3, 0, 0, {0}},
{"friction", (int)offsetof(mjsGeom, friction), 0, 3, 3, 0, {1.0, 0.005, 0.0001}},
{"mass", (int)offsetof(mjsGeom, mass), 0, 1, 0, 1, {0}},
{"density", (int)offsetof(mjsGeom, density), 0, 1, 1, 0, {1000.0}},
{"shellinertia", (int)offsetof(mjsGeom, typeinertia), 2, 1, 0, 0, {0}},
{"solmix", (int)offsetof(mjsGeom, solmix), 0, 1, 1, 0, {1.0}},
{"solref", (int)offsetof(mjsGeom, solref), 4, mjNREF, 2, 0, {0.02, 1.0}},
{"solimp", (int)offsetof(mjsGeom, solimp), 4, mjNIMP, 5, 0, {0.9, 0.95, 0.001, 0.5, 2.0}},
{"margin", (int)offsetof(mjsGeom, margin), 0, 1, 0, 0, {0}},
{"gap", (int)offsetof(mjsGeom, gap), 0, 1, 0, 0, {0}},
{"surfacevel", (int)offsetof(mjsGeom, surfacevel), 0, 6, 0, 0, {0}},
{"adhesion", (int)offsetof(mjsGeom, adhesion), 0, 1, 0, 0, {0}},
{"fromto", (int)offsetof(mjsGeom, fromto), 0, 6, 0, 1, {0}},
{"pos", (int)offsetof(mjsGeom, pos), 0, 3, 3, 0, {0.0, 0.0, 0.0}},
{"quat", (int)offsetof(mjsGeom, quat), 0, 4, 4, 0, {1.0, 0.0, 0.0, 0.0}},
{"fitscale", (int)offsetof(mjsGeom, fitscale), 0, 1, 1, 0, {1.0}},
{"rgba", (int)offsetof(mjsGeom, rgba), 1, 4, 4, 0, {0.5, 0.5, 0.5, 1.0}},
{"fluidshape", (int)offsetof(mjsGeom, fluid_ellipsoid), 4, 1, 0, 0, {0}},
{"fluidcoef", (int)offsetof(mjsGeom, fluid_coefs), 4, 5, 5, 0, {0.5, 0.25, 1.5, 1.0, 1.0}},
};
static const mjXDefaultEntry kDefaults_mjsHField[] = {
{"nrow", (int)offsetof(mjsHField, nrow), 2, 1, 0, 0, {0}},
{"ncol", (int)offsetof(mjsHField, ncol), 2, 1, 0, 0, {0}},
{"size", (int)offsetof(mjsHField, size), 0, 4, 0, 0, {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}},
{"type", (int)offsetof(mjsJoint, type), 2, 1, 1, 0, {(double)mjJNT_HINGE}},
{"group", (int)offsetof(mjsJoint, group), 2, 1, 0, 0, {0}},
{"pos", (int)offsetof(mjsJoint, pos), 0, 3, 0, 0, {0}},
{"axis", (int)offsetof(mjsJoint, axis), 0, 3, 3, 0, {0.0, 0.0, 1.0}},
{"springdamper", (int)offsetof(mjsJoint, springdamper), 0, 2, 0, 0, {0}},
{"limited", (int)offsetof(mjsJoint, limited), 2, 1, 1, 0, {(double)2}},
{"actuatorfrclimited", (int)offsetof(mjsJoint, actfrclimited), 2, 1, 1, 0, {(double)2}},
{"solreflimit", (int)offsetof(mjsJoint, solref_limit), 4, mjNREF, 2, 0, {0.02, 1.0}},
{"solimplimit", (int)offsetof(mjsJoint, solimp_limit), 4, mjNIMP, 5, 0, {0.9, 0.95, 0.001, 0.5, 2.0}},
{"solreffriction", (int)offsetof(mjsJoint, solref_friction), 4, mjNREF, 2, 0, {0.02, 1.0}},
{"solimpfriction", (int)offsetof(mjsJoint, solimp_friction), 4, mjNIMP, 5, 0, {0.9, 0.95, 0.001, 0.5, 2.0}},
{"stiffness", (int)offsetof(mjsJoint, stiffness), 0, mjNPOLY+1, 0, 0, {0}},
{"range", (int)offsetof(mjsJoint, range), 0, 2, 0, 0, {0}},
{"actuatorfrcrange", (int)offsetof(mjsJoint, actfrcrange), 0, 2, 0, 0, {0}},
{"actuatorgravcomp", (int)offsetof(mjsJoint, actgravcomp), 3, 1, 0, 0, {0}},
{"margin", (int)offsetof(mjsJoint, margin), 0, 1, 0, 0, {0}},
{"ref", (int)offsetof(mjsJoint, ref), 0, 1, 0, 0, {0}},
{"springref", (int)offsetof(mjsJoint, springref), 0, 1, 0, 0, {0}},
{"armature", (int)offsetof(mjsJoint, armature), 0, 1, 0, 0, {0}},
{"damping", (int)offsetof(mjsJoint, damping), 0, mjNPOLY+1, 0, 0, {0}},
{"frictionloss", (int)offsetof(mjsJoint, frictionloss), 0, 1, 0, 0, {0}},
};
static const mjXDefaultEntry kDefaults_mjsKey[] = {
{"time", (int)offsetof(mjsKey, time), 0, 1, 0, 0, {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}},
{"type", (int)offsetof(mjsLight, type), 2, 1, 0, 0, {0}},
{"castshadow", (int)offsetof(mjsLight, castshadow), 3, 1, 1, 0, {1}},
{"active", (int)offsetof(mjsLight, active), 3, 1, 1, 0, {1}},
{"pos", (int)offsetof(mjsLight, pos), 0, 3, 3, 0, {0.0, 0.0, 0.0}},
{"dir", (int)offsetof(mjsLight, dir), 0, 3, 3, 0, {0.0, 0.0, -1.0}},
{"bulbradius", (int)offsetof(mjsLight, bulbradius), 1, 1, 1, 0, {0.02}},
{"intensity", (int)offsetof(mjsLight, intensity), 1, 1, 0, 0, {0}},
{"range", (int)offsetof(mjsLight, range), 1, 1, 1, 0, {10.0}},
{"attenuation", (int)offsetof(mjsLight, attenuation), 1, 3, 3, 0, {1.0, 0.0, 0.0}},
{"cutoff", (int)offsetof(mjsLight, cutoff), 1, 1, 1, 0, {45.0}},
{"exponent", (int)offsetof(mjsLight, exponent), 1, 1, 1, 0, {10.0}},
{"ambient", (int)offsetof(mjsLight, ambient), 1, 3, 0, 0, {0}},
{"diffuse", (int)offsetof(mjsLight, diffuse), 1, 3, 3, 0, {0.7, 0.7, 0.7}},
{"specular", (int)offsetof(mjsLight, specular), 1, 3, 3, 0, {0.3, 0.3, 0.3}},
{"mode", (int)offsetof(mjsLight, mode), 2, 1, 1, 0, {(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}},
{"texrepeat", (int)offsetof(mjsMaterial, texrepeat), 1, 2, 2, 0, {1.0, 1.0}},
{"texuniform", (int)offsetof(mjsMaterial, texuniform), 3, 1, 0, 0, {0}},
{"emission", (int)offsetof(mjsMaterial, emission), 1, 1, 0, 0, {0}},
{"specular", (int)offsetof(mjsMaterial, specular), 1, 1, 1, 0, {0.5}},
{"shininess", (int)offsetof(mjsMaterial, shininess), 1, 1, 1, 0, {0.5}},
{"reflectance", (int)offsetof(mjsMaterial, reflectance), 1, 1, 0, 0, {0}},
{"metallic", (int)offsetof(mjsMaterial, metallic), 1, 1, 1, 0, {-1.0}},
{"roughness", (int)offsetof(mjsMaterial, roughness), 1, 1, 1, 0, {-1.0}},
{"rgba", (int)offsetof(mjsMaterial, rgba), 1, 4, 4, 0, {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}},
{"refpos", (int)offsetof(mjsMesh, refpos), 0, 3, 0, 0, {0}},
{"refquat", (int)offsetof(mjsMesh, refquat), 0, 4, 4, 0, {1.0, 0.0, 0.0, 0.0}},
{"scale", (int)offsetof(mjsMesh, scale), 0, 3, 3, 0, {1.0, 1.0, 1.0}},
{"smoothnormal", (int)offsetof(mjsMesh, smoothnormal), 3, 1, 0, 0, {0}},
{"maxhullvert", (int)offsetof(mjsMesh, maxhullvert), 2, 1, 1, 0, {-1.0}},
{"inertia", (int)offsetof(mjsMesh, inertia), 2, 1, 1, 0, {(double)mjMESH_INERTIA_LEGACY}},
};
static const mjXDefaultEntry kDefaults_mjsNumeric[] = {
{"size", (int)offsetof(mjsNumeric, size), 2, 1, 0, 0, {0}},
};
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}},
{"condim", (int)offsetof(mjsPair, condim), 2, 1, 1, 0, {3.0}},
{"friction", (int)offsetof(mjsPair, friction), 0, 5, 5, 0, {1.0, 1.0, 0.005, 0.0001, 0.0001}},
{"solref", (int)offsetof(mjsPair, solref), 4, mjNREF, 2, 0, {0.02, 1.0}},
{"solreffriction", (int)offsetof(mjsPair, solreffriction), 4, mjNREF, 0, 0, {0}},
{"solimp", (int)offsetof(mjsPair, solimp), 4, mjNIMP, 5, 0, {0.9, 0.95, 0.001, 0.5, 2.0}},
{"gap", (int)offsetof(mjsPair, gap), 0, 1, 0, 0, {0}},
{"margin", (int)offsetof(mjsPair, margin), 0, 1, 0, 0, {0}},
{"adhesion", (int)offsetof(mjsPair, adhesion), 0, 1, 0, 0, {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}},
{"nsample", (int)offsetof(mjsSensor, nsample), 2, 1, 0, 0, {0}},
{"interp", (int)offsetof(mjsSensor, interp), 2, 1, 0, 0, {0}},
{"delay", (int)offsetof(mjsSensor, delay), 0, 1, 0, 0, {0}},
{"interval", (int)offsetof(mjsSensor, interval), 0, 2, 0, 0, {0}},
{"cutoff", (int)offsetof(mjsSensor, cutoff), 0, 1, 0, 0, {0}},
{"noise", (int)offsetof(mjsSensor, noise), 0, 1, 0, 0, {0}},
{"objtype", (int)offsetof(mjsSensor, objtype), 2, 1, 0, 0, {0}},
{"reftype", (int)offsetof(mjsSensor, reftype), 2, 1, 0, 0, {0}},
{"datatype", (int)offsetof(mjsSensor, datatype), 2, 1, 1, 0, {(double)mjDATATYPE_REAL}},
{"needstage", (int)offsetof(mjsSensor, needstage), 2, 1, 1, 0, {(double)mjSTAGE_ACC}},
{"dim", (int)offsetof(mjsSensor, dim), 2, 1, 0, 0, {0}},
};
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}},
{"type", (int)offsetof(mjsSite, type), 2, 1, 1, 0, {(double)mjGEOM_SPHERE}},
{"group", (int)offsetof(mjsSite, group), 2, 1, 0, 0, {0}},
{"pos", (int)offsetof(mjsSite, pos), 0, 3, 3, 0, {0.0, 0.0, 0.0}},
{"quat", (int)offsetof(mjsSite, quat), 0, 4, 4, 0, {1.0, 0.0, 0.0, 0.0}},
{"size", (int)offsetof(mjsSite, size), 0, 3, 3, 0, {0.005, 0.005, 0.005}},
{"fromto", (int)offsetof(mjsSite, fromto), 0, 6, 0, 1, {0}},
{"rgba", (int)offsetof(mjsSite, rgba), 1, 4, 4, 0, {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}},
{"rgba", (int)offsetof(mjsSkin, rgba), 1, 4, 4, 0, {0.5, 0.5, 0.5, 1.0}},
{"inflate", (int)offsetof(mjsSkin, inflate), 1, 1, 0, 0, {0}},
{"group", (int)offsetof(mjsSkin, group), 2, 1, 0, 0, {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}},
{"group", (int)offsetof(mjsTendon, group), 2, 1, 0, 0, {0}},
{"limited", (int)offsetof(mjsTendon, limited), 2, 1, 1, 0, {(double)2}},
{"actuatorfrclimited", (int)offsetof(mjsTendon, actfrclimited), 2, 1, 0, 0, {0}},
{"range", (int)offsetof(mjsTendon, range), 0, 2, 0, 0, {0}},
{"actuatorfrcrange", (int)offsetof(mjsTendon, actfrcrange), 0, 2, 0, 0, {0}},
{"solreflimit", (int)offsetof(mjsTendon, solref_limit), 4, mjNREF, 2, 0, {0.02, 1.0}},
{"solimplimit", (int)offsetof(mjsTendon, solimp_limit), 4, mjNIMP, 5, 0, {0.9, 0.95, 0.001, 0.5, 2.0}},
{"solreffriction", (int)offsetof(mjsTendon, solref_friction), 4, mjNREF, 2, 0, {0.02, 1.0}},
{"solimpfriction", (int)offsetof(mjsTendon, solimp_friction), 4, mjNIMP, 5, 0, {0.9, 0.95, 0.001, 0.5, 2.0}},
{"frictionloss", (int)offsetof(mjsTendon, frictionloss), 0, 1, 0, 0, {0}},
{"springlength", (int)offsetof(mjsTendon, springlength), 0, 2, 2, 0, {-1.0, -1.0}},
{"width", (int)offsetof(mjsTendon, width), 0, 1, 1, 0, {0.003}},
{"margin", (int)offsetof(mjsTendon, margin), 0, 1, 0, 0, {0}},
{"stiffness", (int)offsetof(mjsTendon, stiffness), 0, mjNPOLY+1, 0, 0, {0}},
{"damping", (int)offsetof(mjsTendon, damping), 0, mjNPOLY+1, 0, 0, {0}},
{"armature", (int)offsetof(mjsTendon, armature), 0, 1, 0, 0, {0}},
{"rgba", (int)offsetof(mjsTendon, rgba), 1, 4, 4, 0, {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}},
{"type", (int)offsetof(mjsTexture, type), 2, 1, 1, 0, {(double)mjTEXTURE_CUBE}},
{"colorspace", (int)offsetof(mjsTexture, colorspace), 2, 1, 1, 0, {(double)mjCOLORSPACE_AUTO}},
{"gridsize", (int)offsetof(mjsTexture, gridsize), 2, 2, 2, 0, {1.0, 1.0}},
{"builtin", (int)offsetof(mjsTexture, builtin), 2, 1, 0, 0, {0}},
{"rgb1", (int)offsetof(mjsTexture, rgb1), 0, 3, 3, 0, {0.8, 0.8, 0.8}},
{"rgb2", (int)offsetof(mjsTexture, rgb2), 0, 3, 3, 0, {0.5, 0.5, 0.5}},
{"mark", (int)offsetof(mjsTexture, mark), 2, 1, 0, 0, {0}},
{"markrgb", (int)offsetof(mjsTexture, markrgb), 0, 3, 0, 0, {0}},
{"random", (int)offsetof(mjsTexture, random), 0, 1, 1, 0, {0.01}},
{"width", (int)offsetof(mjsTexture, width), 2, 1, 0, 0, {0}},
{"height", (int)offsetof(mjsTexture, height), 2, 1, 0, 0, {0}},
{"hflip", (int)offsetof(mjsTexture, hflip), 3, 1, 0, 0, {0}},
{"vflip", (int)offsetof(mjsTexture, vflip), 3, 1, 0, 0, {0}},
{"nchannel", (int)offsetof(mjsTexture, nchannel), 2, 1, 1, 0, {3.0}},
};
static const mjXDefaultTable kDefaultTables[] = {
{"mjLROpt", kDefaults_mjLROpt, (int)(sizeof(kDefaults_mjLROpt) / sizeof(kDefaults_mjLROpt[0]))},
{"mjOption", kDefaults_mjOption, (int)(sizeof(kDefaults_mjOption) / sizeof(kDefaults_mjOption[0]))},
{"mjSpec", kDefaults_mjSpec, (int)(sizeof(kDefaults_mjSpec) / sizeof(kDefaults_mjSpec[0]))},
{"mjStatistic", kDefaults_mjStatistic, (int)(sizeof(kDefaults_mjStatistic) / sizeof(kDefaults_mjStatistic[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_rgba, (int)(sizeof(kDefaults_mjVisual_rgba) / sizeof(kDefaults_mjVisual_rgba[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]))},
{"mjsCompiler", kDefaults_mjsCompiler, (int)(sizeof(kDefaults_mjsCompiler) / sizeof(kDefaults_mjsCompiler[0]))},
{"mjsEquality", kDefaults_mjsEquality, (int)(sizeof(kDefaults_mjsEquality) / sizeof(kDefaults_mjsEquality[0]))},
{"mjsFlex", kDefaults_mjsFlex, (int)(sizeof(kDefaults_mjsFlex) / sizeof(kDefaults_mjsFlex[0]))},
{"mjsFrame", kDefaults_mjsFrame, (int)(sizeof(kDefaults_mjsFrame) / sizeof(kDefaults_mjsFrame[0]))},
{"mjsGeom", kDefaults_mjsGeom, (int)(sizeof(kDefaults_mjsGeom) / sizeof(kDefaults_mjsGeom[0]))},
{"mjsHField", kDefaults_mjsHField, (int)(sizeof(kDefaults_mjsHField) / sizeof(kDefaults_mjsHField[0]))},
{"mjsJoint", kDefaults_mjsJoint, (int)(sizeof(kDefaults_mjsJoint) / sizeof(kDefaults_mjsJoint[0]))},
{"mjsKey", kDefaults_mjsKey, (int)(sizeof(kDefaults_mjsKey) / sizeof(kDefaults_mjsKey[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]))},
{"mjsNumeric", kDefaults_mjsNumeric, (int)(sizeof(kDefaults_mjsNumeric) / sizeof(kDefaults_mjsNumeric[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]))},
+124 -124
View File
@@ -527,23 +527,23 @@ element mujoco {
#---------------------- compiler -------------------------------------------------------------------
element compiler : mjsCompiler {
autolimits : bool
autolimits : bool = true
boundmass : double
boundinertia : double
settotalmass : double
settotalmass : double = -1
balanceinertia : bool
strippath : bool (reading=custom) # stored on the spec
coordinate : enum<coordinate> (reading=custom) # deprecation error
angle : enum<angle> (field=degree)
angle : enum<angle> = degree (field=degree)
fitaabb : bool
eulerseq : chars[3] (pattern="[xyzXYZ]{3}")
meshdir : string
texturedir : string
discardvisual : bool
usethread : bool
usethread : bool = true
fusestatic : bool
inertiafromgeom : enum<FalseTrueAuto>
inertiagrouprange : int[2]
inertiafromgeom : enum<FalseTrueAuto> = auto
inertiagrouprange : int[2] = {0, 5}
saveinertial : bool
assetdir : string (reading=custom) # fans out to mesh/texturedir
alignfree : bool
@@ -552,16 +552,16 @@ element compiler : mjsCompiler {
}
element lengthrange : mjLROpt {
mode : enum<lrmode>
useexisting : bool
mode : enum<lrmode> = muscle
useexisting : bool = true
uselimit : bool
accel : double
accel : double = 20
maxforce : double
timeconst : double
timestep : double
inttotal : double
interval : double
tolrange : double
timeconst : double = 1
timestep : double = 0.01
inttotal : double = 10
interval : double = 2
tolrange : double = 0.05
}
@@ -581,8 +581,8 @@ element option : mjOption {
density : double
viscosity : double
o_margin : double
o_solref : double[1..mjNREF]
o_solimp : double[1..mjNIMP]
o_solref : double[1..mjNREF] = {0.02, 1}
o_solimp : double[1..mjNIMP] = {0.9, 0.95, 0.001, 0.5, 2}
o_friction : double[1..5] = {1, 1, 0.005, 0.0001, 0.0001}
integrator : enum<integrator> = Euler
cone : enum<cone> = pyramidal
@@ -634,19 +634,19 @@ element flag {
element size : mjSpec {
memory : string (reading=custom) # suffixed byte count
njmax : int (reading=custom) # range/exclusivity checks
nconmax : int (reading=custom) # range check
nstack : int (reading=custom) # range/exclusivity checks
njmax : int = -1 (reading=custom) # range/exclusivity checks
nconmax : int = -1 (reading=custom) # range check
nstack : int = -1 (reading=custom) # range/exclusivity checks
nuserdata : int (min=-1)
nkey : int (min=-1)
nuser_body : int (min=-1)
nuser_jnt : int (min=-1)
nuser_geom : int (min=-1)
nuser_site : int (min=-1)
nuser_cam : int (min=-1)
nuser_tendon : int (min=-1)
nuser_actuator : int (min=-1)
nuser_sensor : int (min=-1)
nuser_body : int = -1 (min=-1)
nuser_jnt : int = -1 (min=-1)
nuser_geom : int = -1 (min=-1)
nuser_site : int = -1 (min=-1)
nuser_cam : int = -1 (min=-1)
nuser_tendon : int = -1 (min=-1)
nuser_actuator : int = -1 (min=-1)
nuser_sensor : int = -1 (min=-1)
exclusive memory nstack
exclusive memory njmax
}
@@ -742,31 +742,31 @@ element scale : mjVisual (field=scale) {
}
element rgba : mjVisual (field=rgba) {
fog : float[4]
haze : float[4]
force : float[4]
inertia : float[4]
joint : float[4]
actuator : float[4]
actuatornegative : float[4]
actuatorpositive : float[4]
com : float[4]
camera : float[4]
light : float[4]
selectpoint : float[4]
connect : float[4]
contactpoint : float[4]
contactforce : float[4]
contactfriction : float[4]
contacttorque : float[4]
contactgap : float[4]
rangefinder : float[4]
constraint : float[4]
slidercrank : float[4]
crankbroken : float[4]
frustum : float[4]
bv : float[4]
bvactive : float[4]
fog : float[4] = {0, 0, 0, 1}
haze : float[4] = {1, 1, 1, 1}
force : float[4] = {1, 0.5, 0.5, 1}
inertia : float[4] = {0.8, 0.2, 0.2, 0.6}
joint : float[4] = {0.2, 0.6, 0.8, 1}
actuator : float[4] = {0.2, 0.25, 0.2, 1}
actuatornegative : float[4] = {0.2, 0.6, 0.9, 1}
actuatorpositive : float[4] = {0.9, 0.4, 0.2, 1}
com : float[4] = {0.9, 0.9, 0.9, 1}
camera : float[4] = {0.6, 0.9, 0.6, 1}
light : float[4] = {0.6, 0.6, 0.9, 1}
selectpoint : float[4] = {0.9, 0.9, 0.1, 1}
connect : float[4] = {0.2, 0.2, 0.8, 1}
contactpoint : float[4] = {0.9, 0.6, 0.2, 1}
contactforce : float[4] = {0.7, 0.9, 0.9, 1}
contactfriction : float[4] = {0.9, 0.8, 0.4, 1}
contacttorque : float[4] = {0.9, 0.7, 0.9, 1}
contactgap : float[4] = {0.5, 0.8, 0.9, 1}
rangefinder : float[4] = {1, 1, 0.1, 1}
constraint : float[4] = {0.9, 0, 0, 1}
slidercrank : float[4] = {0.5, 0.3, 0.8, 1}
crankbroken : float[4] = {0.9, 0, 0, 1}
frustum : float[4] = {1, 1, 0, 0.2}
bv : float[4] = {0, 1, 0, 0.5}
bvactive : float[4] = {1, 0, 0, 0.5}
}
@@ -896,8 +896,8 @@ element bone {
body : ref<body> (required)
bindpos : double[3]
bindquat : double[4]
vertid : double[]
vertweight : double[]
vertid : int[]
vertweight : float[]
}
element texture : mjsTexture {
@@ -981,7 +981,7 @@ element body : mjsBody {
element inertial : mjsBody { # projects into the parent body's i-frame
pos : double[3] (required, field=ipos)
quat : double[4] (reading=custom, field=iquat)
quat : double[4] = {1, 0, 0, 0} (reading=custom, field=iquat)
mass : double (required)
diaginertia : double[3] (field=inertia)
axisangle : double[4] (reading=custom)
@@ -1000,12 +1000,12 @@ element joint : mjsJoint {
pos : double[3] (writing=custom) # saved unless free
axis : double[3] = {0, 0, 1} (writing=custom) # saved for slide/hinge
springdamper : double[2] (writing=custom) # compile directive: saved as stiffness/damping
limited : enum<FalseTrueAuto> (writing=custom) # saved unless free
actuatorfrclimited : enum<FalseTrueAuto> (field=actfrclimited, writing=custom) # saved for slide/hinge
solreflimit : double[1..mjNREF] (field=solref_limit)
solimplimit : double[1..mjNIMP] (field=solimp_limit)
solreffriction : double[1..mjNREF] (field=solref_friction)
solimpfriction : double[1..mjNIMP] (field=solimp_friction)
limited : enum<FalseTrueAuto> = auto (writing=custom) # saved unless free
actuatorfrclimited : enum<FalseTrueAuto> = auto (field=actfrclimited, writing=custom) # saved for slide/hinge
solreflimit : double[1..mjNREF] = {0.02, 1} (field=solref_limit)
solimplimit : double[1..mjNIMP] = {0.9, 0.95, 0.001, 0.5, 2} (field=solimp_limit)
solreffriction : double[1..mjNREF] = {0.02, 1} (field=solref_friction)
solimpfriction : double[1..mjNIMP] = {0.9, 0.95, 0.001, 0.5, 2} (field=solimp_friction)
stiffness : double[1..3] # spring polynomial, 1+mjNPOLY coefficients
range : double[2]
actuatorfrcrange : double[2] (field=actfrcrange)
@@ -1055,7 +1055,7 @@ element geom : mjsGeom {
fitscale : double = 1 (writing=custom) # compile directive: not saved
rgba : float[4] = {0.5, 0.5, 0.5, 1}
fluidshape : enum<fluidshape> (field=fluid_ellipsoid, reading=custom)
fluidcoef : double[1..5] (field=fluid_coefs)
fluidcoef : double[1..5] = {0.5, 0.25, 1.5, 1, 1} (field=fluid_coefs)
user : double[] (field=userdata)
child plugin *
}
@@ -1130,7 +1130,7 @@ element light : mjsLight {
element composite {
prefix : string
type : enum<comp> (required)
count : double[1..3]
count : int[1..3]
offset : double[3]
vertex : double[]
initial : string
@@ -1154,7 +1154,7 @@ element composite_joint (xml=joint) {
solimpfix : double[1..mjNIMP]
type : enum<jointtype>
axis : double[3]
limited : enum<FalseTrueAuto>
limited : enum<FalseTrueAuto> = auto
range : double[2]
margin : double
solreflimit : double[1..mjNREF]
@@ -1168,7 +1168,7 @@ element composite_skin (xml=skin) {
texcoord : bool
material : ref<material>
group : int
rgba : double[4]
rgba : float[4]
inflate : double
subgrid : int
}
@@ -1182,7 +1182,7 @@ element composite_geom (xml=geom) {
priority : int
size : double[1..3]
material : ref<material>
rgba : double[4]
rgba : float[4]
friction : double[1..3]
mass : double
density : double
@@ -1199,7 +1199,7 @@ element composite_site (xml=site) {
group : int
size : double[1..3]
material : ref<material>
rgba : double[4]
rgba : float[4]
}
element flexcomp {
@@ -1208,8 +1208,8 @@ element flexcomp {
group : int
dim : int
dof : enum<fdof>
count : double[3]
cellcount : double[3]
count : int[3]
cellcount : int[3]
spacing : double[3]
radius : double
rigid : bool
@@ -1221,7 +1221,7 @@ element flexcomp {
element : double[]
texcoord : double[]
material : ref<material>
rgba : double[4]
rgba : float[4]
flatskin : bool
pos : double[3]
quat : double[4]
@@ -1249,24 +1249,24 @@ element elasticity : mjsFlex {
young : double
poisson : double
damping : double
thickness : double
thickness : double = -1
elastic2d : enum<elastic2d>
}
element flexcomp_contact : mjsFlex (xml=contact) {
contype : int
conaffinity : int
condim : int
contype : int = 1
conaffinity : int = 1
condim : int = 3
priority : int
friction : double[1..3]
solmix : double
solref : double[1..mjNREF]
solimp : double[1..mjNIMP]
friction : double[1..3] = {1, 0.005, 0.0001}
solmix : double = 1
solref : double[1..mjNREF] = {0.02, 1}
solimp : double[1..mjNIMP] = {0.9, 0.95, 0.001, 0.5, 2}
margin : double
gap : double
internal : bool
selfcollide : enum<flexself>
activelayers : int
selfcollide : enum<flexself> = auto
activelayers : int = 1
passive : bool
}
@@ -1288,10 +1288,10 @@ element deformable {
element flex : mjsFlex {
name : id<flex>
group : int
dim : int
radius : double
dim : int = 2
radius : double = 0.005
material : ref<material>
rgba : float[4]
rgba : float[4] = {0.5, 0.5, 0.5, 1}
flatskin : bool
body : string (required, field=vertbody) # space-separated body names
vertex : double[] (field=vert)
@@ -1299,7 +1299,7 @@ element flex : mjsFlex {
texcoord : float[]
elemtexcoord : int[]
node : string (field=nodebody) # space-separated body names
cellcount : int[3] (reading=custom) # seeded to {1,1,1} before reading
cellcount : int[3] = {1, 1, 1} (reading=custom) # seeded before reading
dof : enum<fdof> (reading=custom) # lowers to interpolation order
child flexcomp_contact ?
child flex_edge ?
@@ -1352,14 +1352,14 @@ element spatial : mjsTendon {
name : id<tendon>
class : ref<default>
group : int
limited : enum<FalseTrueAuto>
limited : enum<FalseTrueAuto> = auto
actuatorfrclimited : enum<FalseTrueAuto> (field=actfrclimited)
range : double[2]
actuatorfrcrange : double[2] (field=actfrcrange)
solreflimit : double[1..mjNREF] (field=solref_limit)
solimplimit : double[1..mjNIMP] (field=solimp_limit)
solreffriction : double[1..mjNREF] (field=solref_friction)
solimpfriction : double[1..mjNIMP] (field=solimp_friction)
solreflimit : double[1..mjNREF] = {0.02, 1} (field=solref_limit)
solimplimit : double[1..mjNIMP] = {0.9, 0.95, 0.001, 0.5, 2} (field=solimp_limit)
solreffriction : double[1..mjNREF] = {0.02, 1} (field=solref_friction)
solimpfriction : double[1..mjNIMP] = {0.9, 0.95, 0.001, 0.5, 2} (field=solimp_friction)
frictionloss : double
springlength : double[1..2] = {-1, -1} (reading=custom) # one value: copied to both
width : double = 0.003
@@ -1395,14 +1395,14 @@ element fixed : mjsTendon {
name : id<tendon>
class : ref<default>
group : int
limited : enum<FalseTrueAuto>
limited : enum<FalseTrueAuto> = auto
actuatorfrclimited : enum<FalseTrueAuto> (field=actfrclimited)
range : double[2]
actuatorfrcrange : double[2] (field=actfrcrange)
solreflimit : double[1..mjNREF] (field=solref_limit)
solimplimit : double[1..mjNIMP] (field=solimp_limit)
solreffriction : double[1..mjNREF] (field=solref_friction)
solimpfriction : double[1..mjNIMP] (field=solimp_friction)
solreflimit : double[1..mjNREF] = {0.02, 1} (field=solref_limit)
solimplimit : double[1..mjNIMP] = {0.9, 0.95, 0.001, 0.5, 2} (field=solimp_limit)
solreffriction : double[1..mjNREF] = {0.02, 1} (field=solref_friction)
solimpfriction : double[1..mjNIMP] = {0.9, 0.95, 0.001, 0.5, 2} (field=solimp_friction)
frictionloss : double
springlength : double[1..2] = {-1, -1} (reading=custom) # one value: copied to both
margin : double
@@ -1509,9 +1509,9 @@ element actuator : mjsActuator {
element general : mjsActuator {
use actuator_base
ctrllimited : enum<FalseTrueAuto>
forcelimited : enum<FalseTrueAuto>
actlimited : enum<FalseTrueAuto>
ctrllimited : enum<FalseTrueAuto> = auto
forcelimited : enum<FalseTrueAuto> = auto
actlimited : enum<FalseTrueAuto> = auto
forcerange : double[2]
actrange : double[2]
use actuator_dynamics
@@ -1532,8 +1532,8 @@ element general : mjsActuator {
element motor : mjsActuator {
use actuator_base
ctrllimited : enum<FalseTrueAuto>
forcelimited : enum<FalseTrueAuto>
ctrllimited : enum<FalseTrueAuto> = auto
forcelimited : enum<FalseTrueAuto> = auto
forcerange : double[2]
use actuator_dynamics
use transmission
@@ -1541,8 +1541,8 @@ element motor : mjsActuator {
element position : mjsActuator {
use actuator_base
ctrllimited : enum<FalseTrueAuto>
forcelimited : enum<FalseTrueAuto>
ctrllimited : enum<FalseTrueAuto> = auto
forcelimited : enum<FalseTrueAuto> = auto
inheritrange : double
forcerange : double[2]
use actuator_dynamics
@@ -1555,8 +1555,8 @@ element position : mjsActuator {
element velocity : mjsActuator {
use actuator_base
ctrllimited : enum<FalseTrueAuto>
forcelimited : enum<FalseTrueAuto>
ctrllimited : enum<FalseTrueAuto> = auto
forcelimited : enum<FalseTrueAuto> = auto
forcerange : double[2]
use actuator_dynamics
use transmission
@@ -1565,9 +1565,9 @@ element velocity : mjsActuator {
element intvelocity : mjsActuator {
use actuator_base
ctrllimited : enum<FalseTrueAuto>
forcelimited : enum<FalseTrueAuto>
actlimited : enum<FalseTrueAuto>
ctrllimited : enum<FalseTrueAuto> = auto
forcelimited : enum<FalseTrueAuto> = auto
actlimited : enum<FalseTrueAuto> = auto
forcerange : double[2]
actrange : double[2]
inheritrange : double
@@ -1580,7 +1580,7 @@ element intvelocity : mjsActuator {
element orientation : mjsActuator {
use actuator_base
forcelimited : enum<FalseTrueAuto>
forcelimited : enum<FalseTrueAuto> = auto
forcerange : double[2]
joint : ref<joint> (nodefault)
site : ref<site> (nodefault)
@@ -1593,8 +1593,8 @@ element orientation : mjsActuator {
element pid : mjsActuator {
use actuator_base
ctrllimited : enum<FalseTrueAuto>
forcelimited : enum<FalseTrueAuto>
ctrllimited : enum<FalseTrueAuto> = auto
forcelimited : enum<FalseTrueAuto> = auto
posrange : double[2] (field=ctrlrange) # alias: the position-setpoint range
velrange : double[2]
ffrange : double[2]
@@ -1613,7 +1613,7 @@ element pid : mjsActuator {
element damper : mjsActuator {
use actuator_base
forcelimited : enum<FalseTrueAuto>
forcelimited : enum<FalseTrueAuto> = auto
forcerange : double[2]
use actuator_dynamics
use transmission
@@ -1622,8 +1622,8 @@ element damper : mjsActuator {
element cylinder : mjsActuator {
use actuator_base
ctrllimited : enum<FalseTrueAuto>
forcelimited : enum<FalseTrueAuto>
ctrllimited : enum<FalseTrueAuto> = auto
forcelimited : enum<FalseTrueAuto> = auto
forcerange : double[2]
use actuator_dynamics
use transmission
@@ -1635,8 +1635,8 @@ element cylinder : mjsActuator {
element muscle : mjsActuator {
use actuator_base
ctrllimited : enum<FalseTrueAuto>
forcelimited : enum<FalseTrueAuto>
ctrllimited : enum<FalseTrueAuto> = auto
forcelimited : enum<FalseTrueAuto> = auto
forcerange : double[2]
use actuator_dynamics
joint : ref<joint> (nodefault)
@@ -1644,7 +1644,7 @@ element muscle : mjsActuator {
tendon : ref<tendon> (nodefault)
slidersite : ref<site> (nodefault)
cranksite : ref<site> (nodefault)
timeconst : double
timeconst : double[2]
tausmooth : double (nodefault)
range : double[2]
force : double
@@ -1658,7 +1658,7 @@ element muscle : mjsActuator {
element adhesion : mjsActuator {
use actuator_base
forcelimited : enum<FalseTrueAuto>
forcelimited : enum<FalseTrueAuto> = auto
forcerange : double[2]
body : ref<body> (nodefault)
gain : double
@@ -1666,7 +1666,7 @@ element adhesion : mjsActuator {
element dcmotor : mjsActuator {
use actuator_base
ctrllimited : enum<FalseTrueAuto>
ctrllimited : enum<FalseTrueAuto> = auto
use actuator_dynamics
use transmission
motorconst : double[1..2]
@@ -1685,9 +1685,9 @@ element actuator_plugin : mjsActuator (xml=plugin) {
use actuator_base
plugin : string
instance : ref<instance>
ctrllimited : enum<FalseTrueAuto>
forcelimited : enum<FalseTrueAuto>
actlimited : enum<FalseTrueAuto>
ctrllimited : enum<FalseTrueAuto> = auto
forcelimited : enum<FalseTrueAuto> = auto
actlimited : enum<FalseTrueAuto> = auto
forcerange : double[2]
actrange : double[2]
use actuator_dynamics
@@ -2268,7 +2268,7 @@ element default_equality (xml=equality) {
element default_tendon (xml=tendon) {
group : int
limited : enum<FalseTrueAuto>
limited : enum<FalseTrueAuto> = auto
range : double[2]
solreflimit : double[1..mjNREF]
solimplimit : double[1..mjNIMP]
@@ -2279,8 +2279,8 @@ element default_tendon (xml=tendon) {
width : double
material : ref<material>
margin : double
stiffness : double
damping : double
rgba : double[4]
stiffness : double[1..3]
damping : double[1..3]
rgba : float[4]
user : double[]
}
+20 -12
View File
@@ -359,17 +359,17 @@ void mjXWriter::OneJoint(XMLElement* elem, const mjCJoint* joint, mjCDef* def,
if (classname != joint->classname && joint->classname != "main") {
WriteAttrTxt(elem, "class", joint->classname);
}
if (joint->type != mjJNT_FREE) {
WriteAttr(elem, "pos", 3, joint->pos);
}
if (joint->type != mjJNT_FREE && joint->type != mjJNT_BALL) {
WriteAttr(elem, "axis", 3, joint->axis);
}
}
// defaults and regular
WriteAttrTable(elem, static_cast<const mjsJoint*>(joint), &def->Joint().spec,
kJointAttrs, kJointAttrsN);
if (joint->type != mjJNT_FREE) {
WriteAttr(elem, "pos", 3, joint->pos, def->Joint().spec.pos);
}
if (joint->type != mjJNT_FREE && joint->type != mjJNT_BALL) {
WriteAttr(elem, "axis", 3, joint->axis, def->Joint().spec.axis);
}
if (joint->type != mjJNT_FREE) {
WriteAttrKey(elem, "limited", FalseTrueAuto_map, 3, joint->limited, def->Joint().limited);
}
@@ -676,25 +676,33 @@ void mjXWriter::OneEquality(XMLElement* elem, const mjCEquality* equality, mjCDe
if (equality->objtype == mjOBJ_BODY) {
WriteAttrTxt(elem, "body1", mjs_getString(equality->name1));
WriteAttrTxt(elem, "body2", mjs_getString(equality->name2));
WriteAttr(elem, "anchor", 3, equality->data);
WriteAttr(elem, "relpose", 7, equality->data+3);
// unlike connect, weld's body semantic does not require anchor,
// and the reader zeroes it when absent: zeros is the default,
// not the constructor's union payload
double zero3[3] = {0, 0, 0};
WriteAttr(elem, "anchor", 3, equality->data, zero3);
WriteAttr(elem, "relpose", 7, equality->data+3,
def->Equality().spec.data+3);
} else {
WriteAttrTxt(elem, "site1", mjs_getString(equality->name1));
WriteAttrTxt(elem, "site2", mjs_getString(equality->name2));
}
WriteAttr(elem, "torquescale", 1, equality->data+10);
WriteAttr(elem, "torquescale", 1, equality->data+10,
def->Equality().spec.data+10);
break;
case mjEQ_JOINT:
WriteAttrTxt(elem, "joint1", mjs_getString(equality->name1));
WriteAttrTxt(elem, "joint2", mjs_getString(equality->name2));
WriteAttr(elem, "polycoef", 5, equality->data);
WriteAttr(elem, "polycoef", 5, equality->data,
def->Equality().spec.data);
break;
case mjEQ_TENDON:
WriteAttrTxt(elem, "tendon1", mjs_getString(equality->name1));
WriteAttrTxt(elem, "tendon2", mjs_getString(equality->name2));
WriteAttr(elem, "polycoef", 5, equality->data);
WriteAttr(elem, "polycoef", 5, equality->data,
def->Equality().spec.data);
break;
case mjEQ_FLEX:
@@ -704,7 +712,7 @@ void mjXWriter::OneEquality(XMLElement* elem, const mjCEquality* equality, mjCDe
case mjEQ_FLEXSTRAIN:
WriteAttrTxt(elem, "flex", mjs_getString(equality->name1));
WriteAttr(elem, "cell", 3, equality->data);
WriteAttr(elem, "cell", 3, equality->data, def->Equality().spec.data);
break;
default:
+24 -2
View File
@@ -13,9 +13,13 @@
// limitations under the License.
// Checks that the attribute defaults declared in mjcf.schema agree with the
// C default-constructors: every generated row is compared against a
// freshly-constructed spec element.
// C default-constructors: every bound numeric attribute is compared against a
// freshly-constructed spec element. Coverage is total, so a nonzero
// constructor default that the schema does not declare is a failure: the
// schema cannot silently under-declare. Fields whose constructor value is
// the mjNAN "unset" sentinel are marked in the table and asserted NaN.
#include <cmath>
#include <map>
#include <string>
@@ -40,6 +44,14 @@ TEST_F(SchemaDefaultsTest, DeclaredDefaultsMatchConstructors) {
std::map<std::string, const void*> objects = {
{"mjOption", &spec->option},
{"mjVisual", &spec->visual},
{"mjStatistic", &spec->stat},
{"mjSpec", spec},
{"mjLROpt", &spec->compiler.LRopt},
{"mjsCompiler", &spec->compiler},
{"mjsFlex", mjs_addFlex(spec)},
{"mjsHField", mjs_addHField(spec)},
{"mjsKey", mjs_addKey(spec)},
{"mjsNumeric", mjs_addNumeric(spec)},
{"mjsBody", body},
{"mjsFrame", mjs_addFrame(body, nullptr)},
{"mjsJoint", mjs_addJoint(body, nullptr)},
@@ -69,6 +81,16 @@ TEST_F(SchemaDefaultsTest, DeclaredDefaultsMatchConstructors) {
for (int j = 0; j < entry.len; j++) {
double expected = j < entry.ndecl ? entry.value[j] : 0;
double actual = 0;
if (entry.unset && j == 0) {
// the constructor holds the mjNAN "unset" sentinel in the first
// slot (the rest are zeros), deliberately undeclared in the schema
double v = entry.kind == 4
? (double)reinterpret_cast<const mjtNum*>(field)[j]
: reinterpret_cast<const double*>(field)[j];
EXPECT_TRUE(std::isnan(v))
<< table.structname << "." << entry.attr << "[" << j << "]";
continue;
}
switch (entry.kind) {
case 0: // double
actual = reinterpret_cast<const double*>(field)[j];
+2 -2
View File
@@ -135,8 +135,8 @@ TEST_F(MujocoTest, SaveXmlShortString) {
std::array<char, 10> out;
EXPECT_THAT(mj_saveXMLString(spec, out.data(), out.size(), error.data(),
error.size()),
273);
EXPECT_STREQ(error.data(), "Output string too short, should be at least 274");
223);
EXPECT_STREQ(error.data(), "Output string too short, should be at least 224");
mj_deleteSpec(spec);
mj_deleteModel(model);
+81
View File
@@ -1638,5 +1638,86 @@ TEST_F(XMLWriterTest, EmptyFlagsAttribute) {
EXPECT_THAT(saved_xml, Not(HasSubstr("output=")));
}
TEST_F(XMLWriterTest, OmitsDefaultJointPosAxis) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body name="b">
<joint name="j" type="hinge"/>
<geom size=".1"/>
</body>
</worldbody>
</mujoco>
)";
MjModelPtr model = LoadModelFromString(xml);
ASSERT_THAT(model.get(), NotNull());
std::string saved_xml = SaveAndReadXml(model.get());
EXPECT_THAT(saved_xml, Not(HasSubstr("pos=\"0 0 0\"")));
EXPECT_THAT(saved_xml, Not(HasSubstr("axis=")));
}
TEST_F(XMLWriterTest, KeepsAuthoredJointPosAxis) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body name="b">
<joint name="j" type="hinge" pos="0 0 0.5" axis="1 0 0"/>
<geom size=".1"/>
</body>
</worldbody>
</mujoco>
)";
MjModelPtr model = LoadModelFromString(xml);
ASSERT_THAT(model.get(), NotNull());
std::string saved_xml = SaveAndReadXml(model.get());
EXPECT_THAT(saved_xml, HasSubstr("pos=\"0 0 0.5\""));
EXPECT_THAT(saved_xml, HasSubstr("axis=\"1 0 0\""));
}
TEST_F(XMLWriterTest, OmitsDefaultEqualityData) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body name="b1"><joint name="j1" type="hinge"/><geom size=".1"/></body>
<body name="b2"><joint name="j2" type="hinge"/><geom size=".1"/></body>
</worldbody>
<equality>
<weld body1="b1" body2="b2"/>
<joint joint1="j1" joint2="j2"/>
</equality>
</mujoco>
)";
MjModelPtr model = LoadModelFromString(xml);
ASSERT_THAT(model.get(), NotNull());
std::string saved_xml = SaveAndReadXml(model.get());
EXPECT_THAT(saved_xml, Not(HasSubstr("anchor=")));
EXPECT_THAT(saved_xml, Not(HasSubstr("torquescale=")));
EXPECT_THAT(saved_xml, Not(HasSubstr("polycoef=")));
// relpose is legitimately saved: the compiler resolves the zero-quat
// "compute current pose" sentinel into the actual relative pose
EXPECT_THAT(saved_xml, HasSubstr("relpose=\"0 0 0 1 0 0 0\""));
}
TEST_F(XMLWriterTest, WritesDefaultClassJointPosAxis) {
// pos and axis set in a default class used to be lost when saving
static constexpr char xml[] = R"(
<mujoco>
<default>
<joint pos="1 2 3" axis="0 1 0"/>
</default>
<worldbody>
<body name="b">
<joint name="j" type="hinge"/>
<geom size=".1"/>
</body>
</worldbody>
</mujoco>
)";
MjModelPtr model = LoadModelFromString(xml);
ASSERT_THAT(model.get(), NotNull());
std::string saved_xml = SaveAndReadXml(model.get());
EXPECT_THAT(saved_xml, HasSubstr("<joint pos=\"1 2 3\" axis=\"0 1 0\"/>"));
}
} // namespace
} // namespace mujoco