diff --git a/doc/changelog.rst b/doc/changelog.rst index 31921d43..faf7006e 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -19,6 +19,7 @@ General - Added :ref:`visual-global` flag :ref:`ellipsoidinertia` to visualize equivalent body inertias with ellipsoids instead of the default boxes. - Added documentation for :ref:`engine plugins`. +- Added struct information to the ``introspect`` module. Python bindings ^^^^^^^^^^^^^^^ @@ -31,6 +32,7 @@ Python bindings state concurrently with the internal ``mj_forward``, resulting in e.g. `MuJoCo stack overflow error`_ or `segmentation fault`_. +- Added a small number of missing struct fields discovered through the new ``introspect`` metadata. Bug fixes ^^^^^^^^^ diff --git a/include/mujoco/mjxmacro.h b/include/mujoco/mjxmacro.h index 94766a30..93575e96 100644 --- a/include/mujoco/mjxmacro.h +++ b/include/mujoco/mjxmacro.h @@ -593,8 +593,11 @@ #define MJDATA_SCALAR \ X( int, nstack ) \ X( int, nbuffer ) \ + X( int, nplugin ) \ X( int, pstack ) \ + X( int, parena ) \ X( int, maxuse_stack ) \ + X( int, maxuse_arena ) \ X( int, maxuse_con ) \ X( int, maxuse_efc ) \ X( int, solver_iter ) \ @@ -606,6 +609,7 @@ X( int, ne ) \ X( int, nf ) \ X( int, nefc ) \ + X( int, nnzJ ) \ X( int, ncon ) \ X( mjtNum, time ) diff --git a/introspect/ast_nodes.py b/introspect/ast_nodes.py index 8f8536cd..926cff42 100644 --- a/introspect/ast_nodes.py +++ b/introspect/ast_nodes.py @@ -22,7 +22,7 @@ from typing import Dict, Optional, Sequence, Tuple, Union # We are relying on Clang to do the actual source parsing and are only doing # a little bit of extra parsing of function parameter type declarations here. # These patterns are here for sanity checking rather than actual parsing. -VALID_TYPE_NAME_PATTERN = re.compile('[A-Za-z_][A-Za-z0-9_]*') +VALID_TYPE_NAME_PATTERN = re.compile('(struct )?[A-Za-z_][A-Za-z0-9_]*') C_INVALID_TYPE_NAMES = frozenset([ 'auto', 'break', 'case', 'const', 'continue', 'default', 'do', 'else', 'enum', 'extern', 'for', 'goto', 'if', 'inline', 'register', 'restrict', @@ -94,7 +94,7 @@ class ArrayType: """Represents a C array type.""" inner_type: Union[ValueType, 'PointerType'] - extents: Tuple[int] + extents: Tuple[int, ...] def __init__(self, inner_type: Union[ValueType, 'PointerType'], extents: Sequence[int]): @@ -169,7 +169,7 @@ class FunctionDecl: name: str return_type: Union[ValueType, ArrayType, PointerType] - parameters: Tuple[FunctionParameterDecl] + parameters: Tuple[FunctionParameterDecl, ...] doc: str def __init__(self, name: str, @@ -218,3 +218,79 @@ class EnumDecl: self.name = name self.declname = declname self.values = _EnumDeclValues(values) + + +@dataclasses.dataclass +class StructFieldDecl: + """Represents a field in a struct or union declaration.""" + + name: str + type: Union[ + ValueType, + ArrayType, + PointerType, + 'AnonymousStructDecl', + 'AnonymousUnionDecl', + ] + doc: str + + def __str__(self): + return self.type.decl(self.name) + + @property + def decltype(self) -> str: + return self.type.decl() + + +@dataclasses.dataclass +class AnonymousStructDecl: + """Represents an anonymous struct declaration.""" + + fields: Tuple[Union[StructFieldDecl, 'AnonymousUnionDecl'], ...] + + def __init__(self, fields: Sequence[StructFieldDecl]): + self.fields = tuple(fields) + + def __str__(self): + return self.decl() + + def _inner_decl(self): + return '; '.join(str(field) for field in self.fields) + ';' + + def decl(self, name_or_decl: Optional[str] = None): + parts = ['struct', f'{{{self._inner_decl()}}}'] + if name_or_decl: + parts.append(name_or_decl) + return ' '.join(parts) + + +class AnonymousUnionDecl(AnonymousStructDecl): + """Represents an anonymous union declaration.""" + + def decl(self, name_or_decl: Optional[str] = None): + parts = ['union', f'{{{self._inner_decl()}}}'] + if name_or_decl: + parts.append(name_or_decl) + return ' '.join(parts) + + +@dataclasses.dataclass +class StructDecl: + """Represents a struct declaration.""" + + name: str + declname: str + fields: Tuple[Union[StructFieldDecl, AnonymousUnionDecl], ...] + + def __init__(self, name: str, + declname: str, + fields: Sequence[Union[StructFieldDecl, AnonymousUnionDecl]]): + self.name = name + self.declname = declname + self.fields = tuple(fields) + + def decl(self, name_or_decl: Optional[str] = None) -> str: + parts = [self.name] + if name_or_decl: + parts.append(name_or_decl) + return ' '.join(parts) diff --git a/introspect/ast_nodes_test.py b/introspect/ast_nodes_test.py index c45f5197..2c642c49 100644 --- a/introspect/ast_nodes_test.py +++ b/introspect/ast_nodes_test.py @@ -118,6 +118,62 @@ class AstNodesTest(absltest.TestCase): complex_type.decl('var'), 'const unsigned int (* * const (* const * var[9])[7])[3][4]') + def test_struct_decl(self): + struct = ast_nodes.StructDecl( + name='mystruct', + declname='struct mystruct_', + fields=[ + ast_nodes.StructFieldDecl( + name='foo', + type=ast_nodes.ValueType('int'), + doc='', + ) + ], + ) + self.assertEqual(struct.decl('var'), 'mystruct var') + + def test_anonymous_struct_decl(self): + struct = ast_nodes.AnonymousStructDecl( + fields=[ + ast_nodes.StructFieldDecl( + name='foo', + type=ast_nodes.ValueType('int'), + doc='', + ), + ast_nodes.StructFieldDecl( + name='bar', + type=ast_nodes.ArrayType( + inner_type=ast_nodes.ValueType('float'), extents=(3,) + ), + doc='', + ), + ], + ) + self.assertEqual(str(struct), 'struct {int foo; float bar[3];}') + self.assertEqual(struct.decl('var'), 'struct {int foo; float bar[3];} var') + self.assertEqual(struct.fields[0].decltype, 'int') + self.assertEqual(struct.fields[1].decltype, 'float [3]') + + def test_anonymous_union_decl(self): + union = ast_nodes.AnonymousUnionDecl( + fields=[ + ast_nodes.StructFieldDecl( + name='foo', + type=ast_nodes.ValueType('int'), + doc='', + ), + ast_nodes.StructFieldDecl( + name='bar', + type=ast_nodes.ArrayType( + inner_type=ast_nodes.ValueType('float'), extents=(3,) + ), + doc='', + ), + ], + ) + self.assertEqual(str(union), 'union {int foo; float bar[3];}') + self.assertEqual(union.decl('var'), 'union {int foo; float bar[3];} var') + if __name__ == '__main__': absltest.main() diff --git a/introspect/codegen/generate_enums.py b/introspect/codegen/generate_enums.py index 20f7d54f..68e9592f 100644 --- a/introspect/codegen/generate_enums.py +++ b/introspect/codegen/generate_enums.py @@ -27,8 +27,7 @@ from absl import flags from introspect import ast_nodes from . import formatter -FLAGS = flags.FLAGS -flags.DEFINE_string( +_JSON_PATH = flags.DEFINE_string( 'json_path', None, 'Path to the JSON file representing the Clang AST for mujoco.h') @@ -85,7 +84,7 @@ def main(argv: Sequence[str]) -> None: if len(argv) > 1: raise app.UsageError('Too many command-line arguments.') - with open(FLAGS.json_path, 'r', encoding='utf-8') as f: + with open(_JSON_PATH.value, 'r', encoding='utf-8') as f: root = json.load(f) visitor = MjEnumVisitor() diff --git a/introspect/codegen/generate_functions.py b/introspect/codegen/generate_functions.py index 6cdf1589..1966e328 100644 --- a/introspect/codegen/generate_functions.py +++ b/introspect/codegen/generate_functions.py @@ -28,9 +28,9 @@ from introspect import ast_nodes from introspect import type_parsing from . import formatter -FLAGS = flags.FLAGS -flags.DEFINE_string('header_path', None, 'Path to the original mujoco.h') -flags.DEFINE_string( +_HEADER_PATH = flags.DEFINE_string( + 'header_path', None, 'Path to the original mujoco.h') +_JSON_PATH = flags.DEFINE_string( 'json_path', None, 'Path to the JSON file representing the Clang AST for mujoco.h') @@ -113,10 +113,10 @@ def main(argv: Sequence[str]) -> None: if len(argv) > 1: raise app.UsageError('Too many command-line arguments.') - with open(FLAGS.json_path, 'r', encoding='utf-8') as f: + with open(_JSON_PATH.value, 'r', encoding='utf-8') as f: root = json.load(f) - with open(FLAGS.header_path, 'r') as f: + with open(_HEADER_PATH.value, 'r') as f: visitor = MjFunctionVisitor(f.read()) traverse(root, visitor) diff --git a/introspect/codegen/generate_structs.py b/introspect/codegen/generate_structs.py new file mode 100644 index 00000000..31ebb050 --- /dev/null +++ b/introspect/codegen/generate_structs.py @@ -0,0 +1,248 @@ +# Copyright 2023 DeepMind Technologies Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Generates structs.py. + +The JSON input can be generated via: + clang -Xclang -ast-dump=json -fsyntax-only -fparse-all-comments -x c mujoco.h +""" + +import itertools +import json +import os +import re +from typing import Any, Mapping, Sequence, Union + +from absl import app +from absl import flags + +from introspect import ast_nodes +from introspect import type_parsing +from . import formatter + +_JSON_PATH = flags.DEFINE_string( + 'json_path', None, + 'Path to the JSON file representing the Clang AST for mujoco.h') + +ClangJsonNode = Mapping[str, Any] + +_ANONYMOUS_KEY_PATTERN = re.compile(r'\d+:\d+(?=\))') +_EXCLUDED = ( + 'mjpPlugin', + 'mjpPlugin_', +) + + +def traverse(node, visitor): + visitor.visit(node) + children = node.get('inner', []) + for child in children: + traverse(child, visitor) + + +class _AnonymousTypePlaceholder(ast_nodes.ValueType): + + def __init__(self, anonymous_key: str): + self.name = anonymous_key + self.is_const = False + self.is_volatile = False + + +class MjStructVisitor: + """A Clang AST JSON node visitor for MuJoCo API struct declarations.""" + + def __init__(self): + self._structs = {} + self._anonymous = {} + self._typedefs = {} + + def _normalize_type( + self, declname: str + ) -> Union[ + ast_nodes.ValueType, ast_nodes.PointerType, ast_nodes.ArrayType]: + """Resolves anonymous structs/unions and looks up existing typedefs.""" + # Check for anonymous struct/union. + if '(unnamed ' in declname: + m = _ANONYMOUS_KEY_PATTERN.search(declname) + if not m: + raise RuntimeError('cannot parse anonymous key from {m!r}') + return _AnonymousTypePlaceholder(m.group(0)) + + # Lookup typedef name and use it instead if one exists. + for k, v in self._typedefs.items(): + if declname == v.declname: + return type_parsing.parse_type(k) + + # No valid normalization, just parse the declname. + return type_parsing.parse_type(declname) + + def _make_comment(self, node: ClangJsonNode) -> str: + """Makes a comment string from a Clang AST FullComment node.""" + kind = node.get('kind') + if kind == 'TextComment': + return node['text'].replace('\N{NO-BREAK SPACE}', ' ').strip() + else: + strings = [] + for child in node['inner']: + strings.append(self._make_comment(child)) + return ''.join(strings).strip() + + def _make_field( + self, node: ClangJsonNode + ) -> Union[ast_nodes.StructFieldDecl, _AnonymousTypePlaceholder]: + """Makes a StructFieldDecl object from a Clang AST FieldDecl node.""" + doc = '' + for child in node.get('inner', ()): + if child['kind'] == 'FullComment': + doc = self._make_comment(child) + if 'name' in node: + field_type = self._normalize_type(node['type']['qualType']) + return ast_nodes.StructFieldDecl( + name=node['name'], type=field_type, doc=doc) + else: + return _AnonymousTypePlaceholder(self._make_anonymous_key(node)) + + def _make_struct( + self, node: ClangJsonNode + ) -> Union[ast_nodes.AnonymousStructDecl, ast_nodes.StructDecl]: + """Makes a Decl object from a Clang AST RecordDecl node.""" + name = f"{node['tagUsed']} {node['name']}" if 'name' in node else '' + fields = [] + for child in node['inner']: + child_kind = child.get('kind') + if child_kind == 'FieldDecl': + fields.append(self._make_field(child)) + + if name: + return ast_nodes.StructDecl(name=name, declname=name, fields=fields) + elif node['tagUsed'] == 'union': + return ast_nodes.AnonymousUnionDecl(fields=fields) + else: + return ast_nodes.AnonymousStructDecl(fields=fields) + + def _is_mujoco_type(self, node: ClangJsonNode) -> bool: + node_name = node.get('name', '') + included_from = os.path.basename( + node['loc'].get('includedFrom', {}).get('file', '') + ) + return node_name not in _EXCLUDED and ( + node_name.startswith('mj') + or included_from == 'mujoco.h' + or included_from.startswith('mj') + ) + + def _make_anonymous_key(self, node: ClangJsonNode) -> str: + line = node['loc']['line'] + col = node['loc']['col'] + return f'{line}:{col}' + + def visit(self, node: ClangJsonNode) -> None: + """Visits a JSON node.""" + if node.get('kind') == 'RecordDecl' and self._is_mujoco_type(node): + struct_decl = self._make_struct(node) + if hasattr(struct_decl, 'name'): + self._structs[struct_decl.name] = struct_decl + else: + anonymous_key = self._make_anonymous_key(node) + if anonymous_key in self._anonymous: + raise RuntimeError( + f'duplicate key for anonymous struct: {anonymous_key}') + self._anonymous[anonymous_key] = struct_decl + elif (node.get('kind') == 'TypedefDecl' and + node['type']['qualType'].startswith('struct mj') and + node['name'] not in _EXCLUDED): + struct = self._structs[node['type']['qualType']] + self._typedefs[node['name']] = ast_nodes.StructDecl( + name=node['name'], declname=struct.declname, fields=struct.fields) + + def resolve_all_anonymous(self) -> None: + """Replaces anonymous struct placeholders with corresponding decl.""" + for struct in itertools.chain( + self._structs.values(), self._typedefs.values() + ): + fields = [] + for field in struct.fields: + if isinstance(field, _AnonymousTypePlaceholder): + fields.append(self._anonymous[field.name]) + elif isinstance(field.type, _AnonymousTypePlaceholder): + fields.append( + ast_nodes.StructFieldDecl( + name=field.name, + type=self._anonymous[field.type.name], + doc=field.doc, + ) + ) + else: + fields.append(field) + struct.fields = tuple(fields) + + @property + def structs(self) -> Mapping[str, ast_nodes.StructDecl]: + return self._structs + + @property + def typedefs(self) -> Mapping[str, ast_nodes.StructDecl]: + return self._typedefs + + +def main(argv: Sequence[str]) -> None: + if len(argv) > 1: + raise app.UsageError('Too many command-line arguments.') + + with open(_JSON_PATH.value, 'r', encoding='utf-8') as f: + root = json.load(f) + + visitor = MjStructVisitor() + + traverse(root, visitor) + visitor.resolve_all_anonymous() + + structs_str = formatter.format_as_python_code(visitor.typedefs) + + print(f''' +# Copyright 2023 DeepMind Technologies Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Provides information about MuJoCo API structs. + +DO NOT EDIT. THIS FILE IS AUTOMATICALLY GENERATED. +""" + +from typing import Mapping + +from .ast_nodes import AnonymousStructDecl +from .ast_nodes import AnonymousUnionDecl +from .ast_nodes import ArrayType +from .ast_nodes import PointerType +from .ast_nodes import StructDecl +from .ast_nodes import StructFieldDecl +from .ast_nodes import ValueType + +STRUCTS: Mapping[str, StructDecl] = {structs_str} +'''.strip()) # `print` adds a trailing newline + + +if __name__ == '__main__': + app.run(main) diff --git a/introspect/enums.py b/introspect/enums.py old mode 100755 new mode 100644 diff --git a/introspect/structs.py b/introspect/structs.py new file mode 100644 index 00000000..16a0ee7c --- /dev/null +++ b/introspect/structs.py @@ -0,0 +1,6191 @@ +# Copyright 2023 DeepMind Technologies Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Provides information about MuJoCo API structs. + +DO NOT EDIT. THIS FILE IS AUTOMATICALLY GENERATED. +""" + +from typing import Mapping + +from .ast_nodes import AnonymousStructDecl +from .ast_nodes import AnonymousUnionDecl +from .ast_nodes import ArrayType +from .ast_nodes import PointerType +from .ast_nodes import StructDecl +from .ast_nodes import StructFieldDecl +from .ast_nodes import ValueType + +STRUCTS: Mapping[str, StructDecl] = dict([ + ('mjLROpt', + StructDecl( + name='mjLROpt', + declname='struct mjLROpt_', + fields=( + StructFieldDecl( + name='mode', + type=ValueType(name='int'), + doc='which actuators to process (mjtLRMode)', + ), + StructFieldDecl( + name='useexisting', + type=ValueType(name='int'), + doc='use existing length range if available', + ), + StructFieldDecl( + name='uselimit', + type=ValueType(name='int'), + doc='use joint and tendon limits if available', + ), + StructFieldDecl( + name='accel', + type=ValueType(name='mjtNum'), + doc='target acceleration used to compute force', + ), + StructFieldDecl( + name='maxforce', + type=ValueType(name='mjtNum'), + doc='maximum force; 0: no limit', + ), + StructFieldDecl( + name='timeconst', + type=ValueType(name='mjtNum'), + doc='time constant for velocity reduction; min 0.01', + ), + StructFieldDecl( + name='timestep', + type=ValueType(name='mjtNum'), + doc='simulation timestep; 0: use mjOption.timestep', + ), + StructFieldDecl( + name='inttotal', + type=ValueType(name='mjtNum'), + doc='total simulation time interval', + ), + StructFieldDecl( + name='interval', + type=ValueType(name='mjtNum'), + doc='evaluation time interval (at the end)', + ), + StructFieldDecl( + name='tolrange', + type=ValueType(name='mjtNum'), + doc='convergence tolerance (relative to range)', + ), + ), + )), + ('mjVFS', + StructDecl( + name='mjVFS', + declname='struct mjVFS_', + fields=( + StructFieldDecl( + name='nfile', + type=ValueType(name='int'), + doc='number of files present', + ), + StructFieldDecl( + name='filename', + type=ArrayType( + inner_type=ValueType(name='char'), + extents=(2000, 1000), + ), + doc='file name without path', + ), + StructFieldDecl( + name='filesize', + type=ArrayType( + inner_type=ValueType(name='int'), + extents=(2000,), + ), + doc='file size in bytes', + ), + StructFieldDecl( + name='filedata', + type=ArrayType( + inner_type=PointerType( + inner_type=ValueType(name='void'), + ), + extents=(2000,), + ), + doc='buffer with file data', + ), + ), + )), + ('mjOption', + StructDecl( + name='mjOption', + declname='struct mjOption_', + fields=( + StructFieldDecl( + name='timestep', + type=ValueType(name='mjtNum'), + doc='timestep', + ), + StructFieldDecl( + name='apirate', + type=ValueType(name='mjtNum'), + doc='update rate for remote API (Hz)', + ), + StructFieldDecl( + name='impratio', + type=ValueType(name='mjtNum'), + doc='ratio of friction-to-normal contact impedance', + ), + StructFieldDecl( + name='tolerance', + type=ValueType(name='mjtNum'), + doc='main solver tolerance', + ), + StructFieldDecl( + name='noslip_tolerance', + type=ValueType(name='mjtNum'), + doc='noslip solver tolerance', + ), + StructFieldDecl( + name='mpr_tolerance', + type=ValueType(name='mjtNum'), + doc='MPR solver tolerance', + ), + StructFieldDecl( + name='gravity', + type=ArrayType( + inner_type=ValueType(name='mjtNum'), + extents=(3,), + ), + doc='gravitational acceleration', + ), + StructFieldDecl( + name='wind', + type=ArrayType( + inner_type=ValueType(name='mjtNum'), + extents=(3,), + ), + doc='wind (for lift, drag and viscosity)', + ), + StructFieldDecl( + name='magnetic', + type=ArrayType( + inner_type=ValueType(name='mjtNum'), + extents=(3,), + ), + doc='global magnetic flux', + ), + StructFieldDecl( + name='density', + type=ValueType(name='mjtNum'), + doc='density of medium', + ), + StructFieldDecl( + name='viscosity', + type=ValueType(name='mjtNum'), + doc='viscosity of medium', + ), + StructFieldDecl( + name='o_margin', + type=ValueType(name='mjtNum'), + doc='margin', + ), + StructFieldDecl( + name='o_solref', + type=ArrayType( + inner_type=ValueType(name='mjtNum'), + extents=(2,), + ), + doc='solref', + ), + StructFieldDecl( + name='o_solimp', + type=ArrayType( + inner_type=ValueType(name='mjtNum'), + extents=(5,), + ), + doc='solimp', + ), + StructFieldDecl( + name='integrator', + type=ValueType(name='int'), + doc='integration mode (mjtIntegrator)', + ), + StructFieldDecl( + name='collision', + type=ValueType(name='int'), + doc='collision mode (mjtCollision)', + ), + StructFieldDecl( + name='cone', + type=ValueType(name='int'), + doc='type of friction cone (mjtCone)', + ), + StructFieldDecl( + name='jacobian', + type=ValueType(name='int'), + doc='type of Jacobian (mjtJacobian)', + ), + StructFieldDecl( + name='solver', + type=ValueType(name='int'), + doc='solver algorithm (mjtSolver)', + ), + StructFieldDecl( + name='iterations', + type=ValueType(name='int'), + doc='maximum number of main solver iterations', + ), + StructFieldDecl( + name='noslip_iterations', + type=ValueType(name='int'), + doc='maximum number of noslip solver iterations', + ), + StructFieldDecl( + name='mpr_iterations', + type=ValueType(name='int'), + doc='maximum number of MPR solver iterations', + ), + StructFieldDecl( + name='disableflags', + type=ValueType(name='int'), + doc='bit flags for disabling standard features', + ), + StructFieldDecl( + name='enableflags', + type=ValueType(name='int'), + doc='bit flags for enabling optional features', + ), + ), + )), + ('mjVisual', + StructDecl( + name='mjVisual', + declname='struct mjVisual_', + fields=( + StructFieldDecl( + name='global', + type=AnonymousStructDecl( + fields=( + StructFieldDecl( + name='fovy', + type=ValueType(name='float'), + doc='y-field of view for free camera (degrees)', + ), + StructFieldDecl( + name='ipd', + type=ValueType(name='float'), + doc='inter-pupilary distance for free camera', + ), + StructFieldDecl( + name='azimuth', + type=ValueType(name='float'), + doc='initial azimuth of free camera (degrees)', + ), + StructFieldDecl( + name='elevation', + type=ValueType(name='float'), + doc='initial elevation of free camera (degrees)', + ), + StructFieldDecl( + name='linewidth', + type=ValueType(name='float'), + doc='line width for wireframe and ray rendering', + ), + StructFieldDecl( + name='glow', + type=ValueType(name='float'), + doc='glow coefficient for selected body', + ), + StructFieldDecl( + name='realtime', + type=ValueType(name='float'), + doc='initial real-time factor (1: real time)', + ), + StructFieldDecl( + name='offwidth', + type=ValueType(name='int'), + doc='width of offscreen buffer', + ), + StructFieldDecl( + name='offheight', + type=ValueType(name='int'), + doc='height of offscreen buffer', + ), + StructFieldDecl( + name='treedepth', + type=ValueType(name='int'), + doc='depth of the bounding volume hierarchy', + ), + StructFieldDecl( + name='ellipsoidinertia', + type=ValueType(name='int'), + doc='geom for inertia visualization (0: box, 1: ellipsoid)', # pylint: disable=line-too-long + ), + ), + ), + doc='', + ), + StructFieldDecl( + name='quality', + type=AnonymousStructDecl( + fields=( + StructFieldDecl( + name='shadowsize', + type=ValueType(name='int'), + doc='size of shadowmap texture', + ), + StructFieldDecl( + name='offsamples', + type=ValueType(name='int'), + doc='number of multisamples for offscreen rendering', # pylint: disable=line-too-long + ), + StructFieldDecl( + name='numslices', + type=ValueType(name='int'), + doc='number of slices for builtin geom drawing', + ), + StructFieldDecl( + name='numstacks', + type=ValueType(name='int'), + doc='number of stacks for builtin geom drawing', + ), + StructFieldDecl( + name='numquads', + type=ValueType(name='int'), + doc='number of quads for box rendering', + ), + ), + ), + doc='', + ), + StructFieldDecl( + name='headlight', + type=AnonymousStructDecl( + fields=( + StructFieldDecl( + name='ambient', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(3,), + ), + doc='ambient rgb (alpha=1)', + ), + StructFieldDecl( + name='diffuse', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(3,), + ), + doc='diffuse rgb (alpha=1)', + ), + StructFieldDecl( + name='specular', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(3,), + ), + doc='specular rgb (alpha=1)', + ), + StructFieldDecl( + name='active', + type=ValueType(name='int'), + doc='is headlight active', + ), + ), + ), + doc='', + ), + StructFieldDecl( + name='map', + type=AnonymousStructDecl( + fields=( + StructFieldDecl( + name='stiffness', + type=ValueType(name='float'), + doc='mouse perturbation stiffness (space->force)', + ), + StructFieldDecl( + name='stiffnessrot', + type=ValueType(name='float'), + doc='mouse perturbation stiffness (space->torque)', + ), + StructFieldDecl( + name='force', + type=ValueType(name='float'), + doc='from force units to space units', + ), + StructFieldDecl( + name='torque', + type=ValueType(name='float'), + doc='from torque units to space units', + ), + StructFieldDecl( + name='alpha', + type=ValueType(name='float'), + doc='scale geom alphas when transparency is enabled', # pylint: disable=line-too-long + ), + StructFieldDecl( + name='fogstart', + type=ValueType(name='float'), + doc='OpenGL fog starts at fogstart * mjModel.stat.extent', # pylint: disable=line-too-long + ), + StructFieldDecl( + name='fogend', + type=ValueType(name='float'), + doc='OpenGL fog ends at fogend * mjModel.stat.extent', # pylint: disable=line-too-long + ), + StructFieldDecl( + name='znear', + type=ValueType(name='float'), + doc='near clipping plane = znear * mjModel.stat.extent', # pylint: disable=line-too-long + ), + StructFieldDecl( + name='zfar', + type=ValueType(name='float'), + doc='far clipping plane = zfar * mjModel.stat.extent', # pylint: disable=line-too-long + ), + StructFieldDecl( + name='haze', + type=ValueType(name='float'), + doc='haze ratio', + ), + StructFieldDecl( + name='shadowclip', + type=ValueType(name='float'), + doc='directional light: shadowclip * mjModel.stat.extent', # pylint: disable=line-too-long + ), + StructFieldDecl( + name='shadowscale', + type=ValueType(name='float'), + doc='spot light: shadowscale * light.cutoff', + ), + StructFieldDecl( + name='actuatortendon', + type=ValueType(name='float'), + doc='scale tendon width', + ), + ), + ), + doc='', + ), + StructFieldDecl( + name='scale', + type=AnonymousStructDecl( + fields=( + StructFieldDecl( + name='forcewidth', + type=ValueType(name='float'), + doc='width of force arrow', + ), + StructFieldDecl( + name='contactwidth', + type=ValueType(name='float'), + doc='contact width', + ), + StructFieldDecl( + name='contactheight', + type=ValueType(name='float'), + doc='contact height', + ), + StructFieldDecl( + name='connect', + type=ValueType(name='float'), + doc='autoconnect capsule width', + ), + StructFieldDecl( + name='com', + type=ValueType(name='float'), + doc='com radius', + ), + StructFieldDecl( + name='camera', + type=ValueType(name='float'), + doc='camera object', + ), + StructFieldDecl( + name='light', + type=ValueType(name='float'), + doc='light object', + ), + StructFieldDecl( + name='selectpoint', + type=ValueType(name='float'), + doc='selection point', + ), + StructFieldDecl( + name='jointlength', + type=ValueType(name='float'), + doc='joint length', + ), + StructFieldDecl( + name='jointwidth', + type=ValueType(name='float'), + doc='joint width', + ), + StructFieldDecl( + name='actuatorlength', + type=ValueType(name='float'), + doc='actuator length', + ), + StructFieldDecl( + name='actuatorwidth', + type=ValueType(name='float'), + doc='actuator width', + ), + StructFieldDecl( + name='framelength', + type=ValueType(name='float'), + doc='bodyframe axis length', + ), + StructFieldDecl( + name='framewidth', + type=ValueType(name='float'), + doc='bodyframe axis width', + ), + StructFieldDecl( + name='constraint', + type=ValueType(name='float'), + doc='constraint width', + ), + StructFieldDecl( + name='slidercrank', + type=ValueType(name='float'), + doc='slidercrank width', + ), + ), + ), + doc='', + ), + StructFieldDecl( + name='rgba', + type=AnonymousStructDecl( + fields=( + StructFieldDecl( + name='fog', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='fog', + ), + StructFieldDecl( + name='haze', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='haze', + ), + StructFieldDecl( + name='force', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='external force', + ), + StructFieldDecl( + name='inertia', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='inertia box', + ), + StructFieldDecl( + name='joint', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='joint', + ), + StructFieldDecl( + name='actuator', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='actuator, neutral', + ), + StructFieldDecl( + name='actuatornegative', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='actuator, negative limit', + ), + StructFieldDecl( + name='actuatorpositive', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='actuator, positive limit', + ), + StructFieldDecl( + name='com', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='center of mass', + ), + StructFieldDecl( + name='camera', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='camera object', + ), + StructFieldDecl( + name='light', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='light object', + ), + StructFieldDecl( + name='selectpoint', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='selection point', + ), + StructFieldDecl( + name='connect', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='auto connect', + ), + StructFieldDecl( + name='contactpoint', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='contact point', + ), + StructFieldDecl( + name='contactforce', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='contact force', + ), + StructFieldDecl( + name='contactfriction', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='contact friction force', + ), + StructFieldDecl( + name='contacttorque', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='contact torque', + ), + StructFieldDecl( + name='contactgap', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='contact point in gap', + ), + StructFieldDecl( + name='rangefinder', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='rangefinder ray', + ), + StructFieldDecl( + name='constraint', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='constraint', + ), + StructFieldDecl( + name='slidercrank', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='slidercrank', + ), + StructFieldDecl( + name='crankbroken', + type=ArrayType( + inner_type=ValueType(name='float'), + extents=(4,), + ), + doc='used when crank must be stretched/broken', + ), + ), + ), + doc='', + ), + ), + )), + ('mjStatistic', + StructDecl( + name='mjStatistic', + declname='struct mjStatistic_', + fields=( + StructFieldDecl( + name='meaninertia', + type=ValueType(name='mjtNum'), + doc='mean diagonal inertia', + ), + StructFieldDecl( + name='meanmass', + type=ValueType(name='mjtNum'), + doc='mean body mass', + ), + StructFieldDecl( + name='meansize', + type=ValueType(name='mjtNum'), + doc='mean body size', + ), + StructFieldDecl( + name='extent', + type=ValueType(name='mjtNum'), + doc='spatial extent', + ), + StructFieldDecl( + name='center', + type=ArrayType( + inner_type=ValueType(name='mjtNum'), + extents=(3,), + ), + doc='center of model', + ), + ), + )), + ('mjModel', + StructDecl( + name='mjModel', + declname='struct mjModel_', + fields=( + StructFieldDecl( + name='nq', + type=ValueType(name='int'), + doc='number of generalized coordinates = dim(qpos)', + ), + StructFieldDecl( + name='nv', + type=ValueType(name='int'), + doc='number of degrees of freedom = dim(qvel)', + ), + StructFieldDecl( + name='nu', + type=ValueType(name='int'), + doc='number of actuators/controls = dim(ctrl)', + ), + StructFieldDecl( + name='na', + type=ValueType(name='int'), + doc='number of activation states = dim(act)', + ), + StructFieldDecl( + name='nbody', + type=ValueType(name='int'), + doc='number of bodies', + ), + StructFieldDecl( + name='nbvh', + type=ValueType(name='int'), + doc='number of total bounding volumes in all bodies', + ), + StructFieldDecl( + name='njnt', + type=ValueType(name='int'), + doc='number of joints', + ), + StructFieldDecl( + name='ngeom', + type=ValueType(name='int'), + doc='number of geoms', + ), + StructFieldDecl( + name='nsite', + type=ValueType(name='int'), + doc='number of sites', + ), + StructFieldDecl( + name='ncam', + type=ValueType(name='int'), + doc='number of cameras', + ), + StructFieldDecl( + name='nlight', + type=ValueType(name='int'), + doc='number of lights', + ), + StructFieldDecl( + name='nmesh', + type=ValueType(name='int'), + doc='number of meshes', + ), + StructFieldDecl( + name='nmeshvert', + type=ValueType(name='int'), + doc='number of vertices in all meshes', + ), + StructFieldDecl( + name='nmeshnormal', + type=ValueType(name='int'), + doc='number of normals in all meshes', + ), + StructFieldDecl( + name='nmeshtexcoord', + type=ValueType(name='int'), + doc='number of texcoords in all meshes', + ), + StructFieldDecl( + name='nmeshface', + type=ValueType(name='int'), + doc='number of triangular faces in all meshes', + ), + StructFieldDecl( + name='nmeshgraph', + type=ValueType(name='int'), + doc='number of ints in mesh auxiliary data', + ), + StructFieldDecl( + name='nskin', + type=ValueType(name='int'), + doc='number of skins', + ), + StructFieldDecl( + name='nskinvert', + type=ValueType(name='int'), + doc='number of vertices in all skins', + ), + StructFieldDecl( + name='nskintexvert', + type=ValueType(name='int'), + doc='number of vertiex with texcoords in all skins', + ), + StructFieldDecl( + name='nskinface', + type=ValueType(name='int'), + doc='number of triangular faces in all skins', + ), + StructFieldDecl( + name='nskinbone', + type=ValueType(name='int'), + doc='number of bones in all skins', + ), + StructFieldDecl( + name='nskinbonevert', + type=ValueType(name='int'), + doc='number of vertices in all skin bones', + ), + StructFieldDecl( + name='nhfield', + type=ValueType(name='int'), + doc='number of heightfields', + ), + StructFieldDecl( + name='nhfielddata', + type=ValueType(name='int'), + doc='number of data points in all heightfields', + ), + StructFieldDecl( + name='ntex', + type=ValueType(name='int'), + doc='number of textures', + ), + StructFieldDecl( + name='ntexdata', + type=ValueType(name='int'), + doc='number of bytes in texture rgb data', + ), + StructFieldDecl( + name='nmat', + type=ValueType(name='int'), + doc='number of materials', + ), + StructFieldDecl( + name='npair', + type=ValueType(name='int'), + doc='number of predefined geom pairs', + ), + StructFieldDecl( + name='nexclude', + type=ValueType(name='int'), + doc='number of excluded geom pairs', + ), + StructFieldDecl( + name='neq', + type=ValueType(name='int'), + doc='number of equality constraints', + ), + StructFieldDecl( + name='ntendon', + type=ValueType(name='int'), + doc='number of tendons', + ), + StructFieldDecl( + name='nwrap', + type=ValueType(name='int'), + doc='number of wrap objects in all tendon paths', + ), + StructFieldDecl( + name='nsensor', + type=ValueType(name='int'), + doc='number of sensors', + ), + StructFieldDecl( + name='nnumeric', + type=ValueType(name='int'), + doc='number of numeric custom fields', + ), + StructFieldDecl( + name='nnumericdata', + type=ValueType(name='int'), + doc='number of mjtNums in all numeric fields', + ), + StructFieldDecl( + name='ntext', + type=ValueType(name='int'), + doc='number of text custom fields', + ), + StructFieldDecl( + name='ntextdata', + type=ValueType(name='int'), + doc='number of mjtBytes in all text fields', + ), + StructFieldDecl( + name='ntuple', + type=ValueType(name='int'), + doc='number of tuple custom fields', + ), + StructFieldDecl( + name='ntupledata', + type=ValueType(name='int'), + doc='number of objects in all tuple fields', + ), + StructFieldDecl( + name='nkey', + type=ValueType(name='int'), + doc='number of keyframes', + ), + StructFieldDecl( + name='nmocap', + type=ValueType(name='int'), + doc='number of mocap bodies', + ), + StructFieldDecl( + name='nplugin', + type=ValueType(name='int'), + doc='number of plugin instances', + ), + StructFieldDecl( + name='npluginattr', + type=ValueType(name='int'), + doc='number of chars in all plugin config attributes', + ), + StructFieldDecl( + name='nuser_body', + type=ValueType(name='int'), + doc='number of mjtNums in body_user', + ), + StructFieldDecl( + name='nuser_jnt', + type=ValueType(name='int'), + doc='number of mjtNums in jnt_user', + ), + StructFieldDecl( + name='nuser_geom', + type=ValueType(name='int'), + doc='number of mjtNums in geom_user', + ), + StructFieldDecl( + name='nuser_site', + type=ValueType(name='int'), + doc='number of mjtNums in site_user', + ), + StructFieldDecl( + name='nuser_cam', + type=ValueType(name='int'), + doc='number of mjtNums in cam_user', + ), + StructFieldDecl( + name='nuser_tendon', + type=ValueType(name='int'), + doc='number of mjtNums in tendon_user', + ), + StructFieldDecl( + name='nuser_actuator', + type=ValueType(name='int'), + doc='number of mjtNums in actuator_user', + ), + StructFieldDecl( + name='nuser_sensor', + type=ValueType(name='int'), + doc='number of mjtNums in sensor_user', + ), + StructFieldDecl( + name='nnames', + type=ValueType(name='int'), + doc='number of chars in all names', + ), + StructFieldDecl( + name='nnames_map', + type=ValueType(name='int'), + doc='number of slots in the names hash map', + ), + StructFieldDecl( + name='nM', + type=ValueType(name='int'), + doc='number of non-zeros in sparse inertia matrix', + ), + StructFieldDecl( + name='nD', + type=ValueType(name='int'), + doc='number of non-zeros in sparse dof-dof matrix', + ), + StructFieldDecl( + name='nB', + type=ValueType(name='int'), + doc='number of non-zeros in sparse body-dof matrix', + ), + StructFieldDecl( + name='nemax', + type=ValueType(name='int'), + doc='number of potential equality-constraint rows', + ), + StructFieldDecl( + name='njmax', + type=ValueType(name='int'), + doc='number of available rows in constraint Jacobian', + ), + StructFieldDecl( + name='nconmax', + type=ValueType(name='int'), + doc='number of potential contacts in contact list', + ), + StructFieldDecl( + name='nstack', + type=ValueType(name='int'), + doc='number of fields in mjData stack', + ), + StructFieldDecl( + name='nuserdata', + type=ValueType(name='int'), + doc='number of extra fields in mjData', + ), + StructFieldDecl( + name='nsensordata', + type=ValueType(name='int'), + doc='number of fields in sensor data vector', + ), + StructFieldDecl( + name='npluginstate', + type=ValueType(name='int'), + doc='number of fields in the plugin state vector', + ), + StructFieldDecl( + name='nbuffer', + type=ValueType(name='int'), + doc='number of bytes in buffer', + ), + StructFieldDecl( + name='opt', + type=ValueType(name='mjOption'), + doc='physics options', + ), + StructFieldDecl( + name='vis', + type=ValueType(name='mjVisual'), + doc='visualization options', + ), + StructFieldDecl( + name='stat', + type=ValueType(name='mjStatistic'), + doc='model statistics', + ), + StructFieldDecl( + name='buffer', + type=PointerType( + inner_type=ValueType(name='void'), + ), + doc='main buffer; all pointers point in it (nbuffer)', + ), + StructFieldDecl( + name='qpos0', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='qpos values at default pose (nq x 1)', + ), + StructFieldDecl( + name='qpos_spring', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='reference pose for springs (nq x 1)', + ), + StructFieldDecl( + name='body_parentid', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc="id of body's parent (nbody x 1)", + ), + StructFieldDecl( + name='body_rootid', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='id of root above body (nbody x 1)', + ), + StructFieldDecl( + name='body_weldid', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='id of body that this body is welded to (nbody x 1)', + ), + StructFieldDecl( + name='body_mocapid', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='id of mocap data; -1: none (nbody x 1)', + ), + StructFieldDecl( + name='body_jntnum', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='number of joints for this body (nbody x 1)', + ), + StructFieldDecl( + name='body_jntadr', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='start addr of joints; -1: no joints (nbody x 1)', + ), + StructFieldDecl( + name='body_dofnum', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='number of motion degrees of freedom (nbody x 1)', + ), + StructFieldDecl( + name='body_dofadr', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='start addr of dofs; -1: no dofs (nbody x 1)', + ), + StructFieldDecl( + name='body_geomnum', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='number of geoms (nbody x 1)', + ), + StructFieldDecl( + name='body_geomadr', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='start addr of geoms; -1: no geoms (nbody x 1)', + ), + StructFieldDecl( + name='body_simple', + type=PointerType( + inner_type=ValueType(name='mjtByte'), + ), + doc='body is simple (has diagonal M) (nbody x 1)', + ), + StructFieldDecl( + name='body_sameframe', + type=PointerType( + inner_type=ValueType(name='mjtByte'), + ), + doc='inertial frame is same as body frame (nbody x 1)', + ), + StructFieldDecl( + name='body_pos', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='position offset rel. to parent body (nbody x 3)', + ), + StructFieldDecl( + name='body_quat', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='orientation offset rel. to parent body (nbody x 4)', + ), + StructFieldDecl( + name='body_ipos', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='local position of center of mass (nbody x 3)', + ), + StructFieldDecl( + name='body_iquat', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='local orientation of inertia ellipsoid (nbody x 4)', + ), + StructFieldDecl( + name='body_mass', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='mass (nbody x 1)', + ), + StructFieldDecl( + name='body_subtreemass', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='mass of subtree starting at this body (nbody x 1)', + ), + StructFieldDecl( + name='body_inertia', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='diagonal inertia in ipos/iquat frame (nbody x 3)', + ), + StructFieldDecl( + name='body_invweight0', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='mean inv inert in qpos0 (trn, rot) (nbody x 2)', + ), + StructFieldDecl( + name='body_gravcomp', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='antigravity force, units of body weight (nbody x 1)', + ), + StructFieldDecl( + name='body_user', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='user data (nbody x nuser_body)', # pylint: disable=line-too-long + ), + StructFieldDecl( + name='body_plugin', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='plugin instance id; -1: not in use (nbody x 1)', + ), + StructFieldDecl( + name='body_bvhadr', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='address of bvh root (nbody x 1)', + ), + StructFieldDecl( + name='body_bvhnum', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='number of bounding volumes (nbody x 1)', + ), + StructFieldDecl( + name='bvh_depth', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='depth in the bounding volume hierarchy (nbvh x 1)', + ), + StructFieldDecl( + name='bvh_child', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='left and right children in tree (nbvh x 2)', + ), + StructFieldDecl( + name='bvh_geomid', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='geom id of the node; -1: non-leaf (nbvh x 1)', + ), + StructFieldDecl( + name='bvh_aabb', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='bounding box of node (center, size) (nbvh x 6)', + ), + StructFieldDecl( + name='jnt_type', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='type of joint (mjtJoint) (njnt x 1)', + ), + StructFieldDecl( + name='jnt_qposadr', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc="start addr in 'qpos' for joint's data (njnt x 1)", + ), + StructFieldDecl( + name='jnt_dofadr', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc="start addr in 'qvel' for joint's data (njnt x 1)", + ), + StructFieldDecl( + name='jnt_bodyid', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc="id of joint's body (njnt x 1)", + ), + StructFieldDecl( + name='jnt_group', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='group for visibility (njnt x 1)', + ), + StructFieldDecl( + name='jnt_limited', + type=PointerType( + inner_type=ValueType(name='mjtByte'), + ), + doc='does joint have limits (njnt x 1)', + ), + StructFieldDecl( + name='jnt_solref', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='constraint solver reference: limit (njnt x mjNREF)', + ), + StructFieldDecl( + name='jnt_solimp', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='constraint solver impedance: limit (njnt x mjNIMP)', + ), + StructFieldDecl( + name='jnt_pos', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='local anchor position (njnt x 3)', + ), + StructFieldDecl( + name='jnt_axis', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='local joint axis (njnt x 3)', + ), + StructFieldDecl( + name='jnt_stiffness', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='stiffness coefficient (njnt x 1)', + ), + StructFieldDecl( + name='jnt_range', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='joint limits (njnt x 2)', + ), + StructFieldDecl( + name='jnt_margin', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='min distance for limit detection (njnt x 1)', + ), + StructFieldDecl( + name='jnt_user', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='user data (njnt x nuser_jnt)', # pylint: disable=line-too-long + ), + StructFieldDecl( + name='dof_bodyid', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc="id of dof's body (nv x 1)", + ), + StructFieldDecl( + name='dof_jntid', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc="id of dof's joint (nv x 1)", + ), + StructFieldDecl( + name='dof_parentid', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc="id of dof's parent; -1: none (nv x 1)", + ), + StructFieldDecl( + name='dof_Madr', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='dof address in M-diagonal (nv x 1)', + ), + StructFieldDecl( + name='dof_simplenum', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='number of consecutive simple dofs (nv x 1)', + ), + StructFieldDecl( + name='dof_solref', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='constraint solver reference:frictionloss (nv x mjNREF)', + ), + StructFieldDecl( + name='dof_solimp', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='constraint solver impedance:frictionloss (nv x mjNIMP)', + ), + StructFieldDecl( + name='dof_frictionloss', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='dof friction loss (nv x 1)', + ), + StructFieldDecl( + name='dof_armature', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='dof armature inertia/mass (nv x 1)', + ), + StructFieldDecl( + name='dof_damping', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='damping coefficient (nv x 1)', + ), + StructFieldDecl( + name='dof_invweight0', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='diag. inverse inertia in qpos0 (nv x 1)', + ), + StructFieldDecl( + name='dof_M0', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='diag. inertia in qpos0 (nv x 1)', + ), + StructFieldDecl( + name='geom_type', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='geometric type (mjtGeom) (ngeom x 1)', + ), + StructFieldDecl( + name='geom_contype', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='geom contact type (ngeom x 1)', + ), + StructFieldDecl( + name='geom_conaffinity', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='geom contact affinity (ngeom x 1)', + ), + StructFieldDecl( + name='geom_condim', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='contact dimensionality (1, 3, 4, 6) (ngeom x 1)', + ), + StructFieldDecl( + name='geom_bodyid', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc="id of geom's body (ngeom x 1)", + ), + StructFieldDecl( + name='geom_dataid', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc="id of geom's mesh/hfield; -1: none (ngeom x 1)", + ), + StructFieldDecl( + name='geom_matid', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='material id for rendering; -1: none (ngeom x 1)', + ), + StructFieldDecl( + name='geom_group', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='group for visibility (ngeom x 1)', + ), + StructFieldDecl( + name='geom_priority', + type=PointerType( + inner_type=ValueType(name='int'), + ), + doc='geom contact priority (ngeom x 1)', + ), + StructFieldDecl( + name='geom_sameframe', + type=PointerType( + inner_type=ValueType(name='mjtByte'), + ), + doc='same as body frame (1) or iframe (2) (ngeom x 1)', + ), + StructFieldDecl( + name='geom_solmix', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='mixing coef for solref/imp in geom pair (ngeom x 1)', + ), + StructFieldDecl( + name='geom_solref', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='constraint solver reference: contact (ngeom x mjNREF)', # pylint: disable=line-too-long + ), + StructFieldDecl( + name='geom_solimp', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='constraint solver impedance: contact (ngeom x mjNIMP)', # pylint: disable=line-too-long + ), + StructFieldDecl( + name='geom_size', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='geom-specific size parameters (ngeom x 3)', + ), + StructFieldDecl( + name='geom_aabb', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='bounding box, (center, size) (ngeom x 6)', + ), + StructFieldDecl( + name='geom_rbound', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='radius of bounding sphere (ngeom x 1)', + ), + StructFieldDecl( + name='geom_pos', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='local position offset rel. to body (ngeom x 3)', + ), + StructFieldDecl( + name='geom_quat', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='local orientation offset rel. to body (ngeom x 4)', + ), + StructFieldDecl( + name='geom_friction', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='friction for (slide, spin, roll) (ngeom x 3)', + ), + StructFieldDecl( + name='geom_margin', + type=PointerType( + inner_type=ValueType(name='mjtNum'), + ), + doc='detect contact if dist 1: - ValueError('duplicate qualifier: {part!r}') + raise ValueError('duplicate qualifier: {part!r}') else: non_qualifiers.append(part) is_qualifier = dict() diff --git a/python/mujoco/render.cc b/python/mujoco/render.cc index 6c38348d..e6a27983 100644 --- a/python/mujoco/render.cc +++ b/python/mujoco/render.cc @@ -214,6 +214,7 @@ PYBIND11_MODULE(_render, pymodule) { X(windowStereo); X(windowDoublebuffer); X(currentBuffer); + X(readPixelFormat); #undef X #define X(var) \ diff --git a/python/mujoco/structs.cc b/python/mujoco/structs.cc index fc586069..f490b64b 100644 --- a/python/mujoco/structs.cc +++ b/python/mujoco/structs.cc @@ -23,10 +23,8 @@ #include #include #include -#include #include #include -#include #include #include #include @@ -2167,6 +2165,7 @@ This is useful for example when the MJB is not available as a file on disk.)")); }) X(maxgeom); X(ngeom); + X(nskin); X(nlight); X(enabletransform); X(scale); @@ -2228,6 +2227,7 @@ This is useful for example when the MJB is not available as a file on disk.)")); X(textrgb); X(linergb); X(range); + X(highlight); X(linepnt); X(linedata); X(xaxispixel);