Skip to content

Commit 05c1f4c

Browse files
authored
Merge branch 'google-deepmind:main' into musculoskeletal_dog_creation
2 parents 143b416 + c710837 commit 05c1f4c

10 files changed

Lines changed: 146 additions & 32 deletions

File tree

dm_control/autowrap/header_parsing.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,19 @@ def _nested_if_else(if_, pred, else_, endif, match_if_true, match_if_false):
7878
return ifelse
7979

8080

81+
def _nested_ifn_else(ifn_, pred, else_, endif, match_if_true, match_if_false):
82+
"""Constructs a parser for (possibly nested) if...(else)...endif blocks."""
83+
ifnelse = pp.Forward()
84+
ifnelse << pp.Group( # pylint: disable=expression-not-assigned
85+
ifn_ +
86+
pred("predicate") +
87+
pp.ZeroOrMore(match_if_true | ifnelse)("if_false") +
88+
pp.Optional(else_ +
89+
pp.ZeroOrMore(match_if_false | ifnelse)("if_true")) +
90+
endif)
91+
return ifnelse
92+
93+
8194
# Some common string patterns to suppress.
8295
# ------------------------------------------------------------------------------
8396
(LPAREN, RPAREN, LBRACK, RBRACK, LBRACE, RBRACE, SEMI, COMMA, EQUAL, FSLASH,
@@ -189,7 +202,9 @@ def _nested_if_else(if_, pred, else_, endif, match_if_true, match_if_false):
189202
UNCOND_DECL = DEF_FLAG | DEF_CONST | TYPE_DECL
190203

191204
# Declarations inside (possibly nested) #if(n)def... #else... #endif... blocks.
192-
COND_DECL = _nested_if_else(IFDEF, NAME, ELSE, ENDIF, UNCOND_DECL, UNCOND_DECL)
205+
COND_DECL = _nested_if_else(
206+
IFDEF, NAME, ELSE, ENDIF, UNCOND_DECL, UNCOND_DECL
207+
) | _nested_ifn_else(IFNDEF, NAME, ELSE, ENDIF, UNCOND_DECL, UNCOND_DECL)
193208
# Note: this doesn't work for '#if defined(FLAG)' blocks
194209

195210
# e.g. "mjtNum gravity[3]; // gravitational acceleration"

dm_control/composer/entity.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,8 @@ def set_pose(self, physics, position=None, quaternion=None):
480480
if position is not None:
481481
physics.bind(root_joint).qpos[:3] = position
482482
if quaternion is not None:
483-
physics.bind(root_joint).qpos[3:] = quaternion
483+
normalised_quaternion = quaternion / np.linalg.norm(quaternion)
484+
physics.bind(root_joint).qpos[3:] = normalised_quaternion
484485
else:
485486
attachment_frame = mjcf.get_attachment_frame(self.mjcf_model)
486487
if attachment_frame is None:
@@ -521,7 +522,7 @@ def shift_pose(self,
521522
if position is not None:
522523
new_position = current_position + position
523524
if quaternion is not None:
524-
quaternion = np.array(quaternion, dtype=np.float64, copy=False)
525+
quaternion = np.asarray(quaternion, dtype=np.float64)
525526
new_quaternion = _multiply_quaternions(quaternion, current_quaternion)
526527
root_joint = mjcf.get_frame_freejoint(self.mjcf_model)
527528
if root_joint and rotate_velocity:

dm_control/locomotion/tasks/reference_pose/tracking_test.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,9 @@ def test_prop_factory(self):
215215

216216
# Test that props go to the expected location on reset.
217217
for ref_key, obs_key in zip(REFERENCE_PROP_KEYS, PROP_OBSERVATION_KEYS):
218-
np.testing.assert_array_equal(observation[ref_key], observation[obs_key])
218+
np.testing.assert_array_almost_equal(
219+
observation[ref_key], observation[obs_key]
220+
)
219221

220222
def test_ghost_prop(self):
221223
task = tracking.MultiClipMocapTracking(
@@ -242,7 +244,7 @@ def test_ghost_prop(self):
242244
np.squeeze(observation[key]) for key in REFERENCE_PROP_KEYS)
243245

244246
np.testing.assert_array_equal(np.array(ghost_pos), goal_pos + GHOST_OFFSET)
245-
np.testing.assert_array_equal(ghost_quat, goal_quat)
247+
np.testing.assert_array_almost_equal(ghost_quat, goal_quat)
246248

247249
def test_disable_props(self):
248250
task = tracking.MultiClipMocapTracking(

dm_control/locomotion/walkers/rescale.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
def rescale_subtree(body, position_factor, size_factor):
2222
"""Recursively rescales an entire subtree of an MJCF model."""
2323
for child in body.all_children():
24+
if child.tag == 'sensor':
25+
continue
2426
if getattr(child, 'fromto', None) is not None:
2527
new_pos = position_factor * 0.5 * (child.fromto[3:] + child.fromto[:3])
2628
new_size = size_factor * 0.5 * (child.fromto[3:] - child.fromto[:3])

dm_control/mjcf/schema.xml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,53 @@
909909
<attribute name="hflip" type="keyword" valid_values="false true"/>
910910
<attribute name="vflip" type="keyword" valid_values="false true"/>
911911
</attributes>
912+
<children>
913+
<element name="rgb" repeated="false">
914+
<attributes>
915+
<attribute name="texture" type="reference" required="false" reference_namespace="texture"/>
916+
</attributes>
917+
</element>
918+
<element name="normal" repeated="false">
919+
<attributes>
920+
<attribute name="texture" type="reference" required="false" reference_namespace="texture"/>
921+
</attributes>
922+
</element>
923+
<element name="occlusion" repeated="false">
924+
<attributes>
925+
<attribute name="texture" type="reference" required="false" reference_namespace="texture"/>
926+
</attributes>
927+
</element>
928+
<element name="roughness" repeated="false">
929+
<attributes>
930+
<attribute name="texture" type="reference" required="false" reference_namespace="texture"/>
931+
</attributes>
932+
</element>
933+
<element name="metallic" repeated="false">
934+
<attributes>
935+
<attribute name="texture" type="reference" required="false" reference_namespace="texture"/>
936+
</attributes>
937+
</element>
938+
<element name="opacity" repeated="false">
939+
<attributes>
940+
<attribute name="texture" type="reference" required="false" reference_namespace="texture"/>
941+
</attributes>
942+
</element>
943+
<element name="emissive" repeated="false">
944+
<attributes>
945+
<attribute name="texture" type="reference" required="false" reference_namespace="texture"/>
946+
</attributes>
947+
</element>
948+
<element name="orm" repeated="false">
949+
<attributes>
950+
<attribute name="texture" type="reference" required="false" reference_namespace="texture"/>
951+
</attributes>
952+
</element>
953+
<element name="rgba" repeated="false">
954+
<attributes>
955+
<attribute name="texture" type="reference" required="false" reference_namespace="texture"/>
956+
</attributes>
957+
</element>
958+
</children>
912959
</element>
913960
<element name="hfield" repeated="true">
914961
<attributes>
@@ -2167,6 +2214,7 @@
21672214
<attribute name="forcerange" type="array" array_type="float" array_size="2"/>
21682215
<attribute name="actrange" type="array" array_type="float" array_size="2"/>
21692216
<attribute name="lengthrange" type="array" array_type="float" array_size="2"/>
2217+
<attribute name="actdim" type="int"/>
21702218
<attribute name="dyntype" type="keyword" valid_values="none integrator filter filterexact muscle user"/>
21712219
<attribute name="dynprm" type="array" array_type="float" array_size="10"/>
21722220
<attribute name="gear" type="array" array_type="float" array_size="6"/>
@@ -2572,6 +2620,42 @@
25722620
</element>
25732621
</children>
25742622
</element>
2623+
<element name="fromto" repeated="true" namespace="sensor">
2624+
<attributes>
2625+
<attribute name="name" type="identifier"/>
2626+
<attribute name="noise" type="float"/>
2627+
<attribute name="user" type="array" array_type="float"/>
2628+
<attribute name="cutoff" type="float"/>
2629+
<attribute name="geom1" type="reference" required="true" reference_namespace="geom"/>
2630+
<attribute name="geom2" type="reference" required="true" reference_namespace="geom"/>
2631+
<attribute name="body1" type="reference" required="true" reference_namespace="body"/>
2632+
<attribute name="body2" type="reference" required="true" reference_namespace="body"/>
2633+
</attributes>
2634+
</element>
2635+
<element name="normal" repeated="true" namespace="sensor">
2636+
<attributes>
2637+
<attribute name="name" type="identifier"/>
2638+
<attribute name="noise" type="float"/>
2639+
<attribute name="user" type="array" array_type="float"/>
2640+
<attribute name="cutoff" type="float"/>
2641+
<attribute name="geom1" type="reference" required="true" reference_namespace="geom"/>
2642+
<attribute name="geom2" type="reference" required="true" reference_namespace="geom"/>
2643+
<attribute name="body1" type="reference" required="true" reference_namespace="body"/>
2644+
<attribute name="body2" type="reference" required="true" reference_namespace="body"/>
2645+
</attributes>
2646+
</element>
2647+
<element name="distance" repeated="true" namespace="sensor">
2648+
<attributes>
2649+
<attribute name="name" type="identifier"/>
2650+
<attribute name="noise" type="float"/>
2651+
<attribute name="user" type="array" array_type="float"/>
2652+
<attribute name="cutoff" type="float"/>
2653+
<attribute name="geom1" type="reference" required="true" reference_namespace="geom"/>
2654+
<attribute name="geom2" type="reference" required="true" reference_namespace="geom"/>
2655+
<attribute name="body1" type="reference" required="true" reference_namespace="body"/>
2656+
<attribute name="body2" type="reference" required="true" reference_namespace="body"/>
2657+
</attributes>
2658+
</element>
25752659
</children>
25762660
</element>
25772661
<element name="keyframe">

dm_control/mujoco/index.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ def convert_key_item(self, key_item):
355355

356356
elif isinstance(key_item, (list, np.ndarray)):
357357
# Cast lists to numpy arrays.
358-
key_item = np.array(key_item, copy=False)
358+
key_item = np.asarray(key_item)
359359
original_shape = key_item.shape
360360

361361
# We assume that either all or none of the items in the array are strings

dm_control/mujoco/tutorial.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
"\"\"\")\n",
9494
"\n",
9595
"print('Installing dm_control...')\n",
96-
"!pip install -q dm_control\u003e=1.0.20\n",
96+
"!pip install -q dm_control\u003e=1.0.22\n",
9797
"\n",
9898
"# Configure dm_control to use the EGL rendering backend (requires GPU)\n",
9999
"%env MUJOCO_GL=egl\n",

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ h5py==3.11.0
66
labmaze==1.0.6
77
lxml==5.2.2
88
mock==5.1.0
9-
mujoco==3.1.6
9+
mujoco==3.2.1
1010
nose==1.3.7
1111
nose-xunitmp==0.4.1
1212
numpy==1.24.4; python_version == '3.8'

setup.py

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,16 @@ def _finalize_mjbindings_options(cmd_instance):
7171

7272
class BuildMJBindingsCommand(setuptools.Command):
7373
"""Runs `autowrap.py` to generate the low-level ctypes bindings for MuJoCo."""
74+
7475
description = __doc__
7576
user_options = [
7677
# The format is (long option, short option, description).
77-
('headers-dir=', None,
78-
'Path to directory containing MuJoCo headers.'),
79-
('inplace=', None,
80-
'Place generated files in source directory rather than `build-lib`.'),
78+
('headers-dir=', None, 'Path to directory containing MuJoCo headers.'),
79+
(
80+
'inplace=',
81+
None,
82+
'Place generated files in source directory rather than `build-lib`.',
83+
),
8184
]
8285
boolean_options = ['inplace']
8386

@@ -99,7 +102,7 @@ def run(self):
99102
sys.executable or 'python',
100103
AUTOWRAP_PATH,
101104
'--header_paths={}'.format(self.header_paths),
102-
'--output_dir={}'.format(output_dir)
105+
'--output_dir={}'.format(output_dir),
103106
]
104107
self.announce('Running command: {}'.format(command), level=logging.DEBUG)
105108
try:
@@ -119,9 +122,11 @@ class InstallCommand(install.install):
119122
"""Runs 'build_mjbindings' before installation."""
120123

121124
user_options = (
122-
install.install.user_options + BuildMJBindingsCommand.user_options)
125+
install.install.user_options + BuildMJBindingsCommand.user_options
126+
)
123127
boolean_options = (
124-
install.install.boolean_options + BuildMJBindingsCommand.boolean_options)
128+
install.install.boolean_options + BuildMJBindingsCommand.boolean_options
129+
)
125130

126131
def initialize_options(self):
127132
install.install.initialize_options(self)
@@ -132,9 +137,7 @@ def finalize_options(self):
132137
_finalize_mjbindings_options(self)
133138

134139
def run(self):
135-
self.reinitialize_command('build_mjbindings',
136-
inplace=self.inplace,
137-
headers_dir=self.headers_dir)
140+
self.reinitialize_command('build_mjbindings')
138141
self.run_command('build_mjbindings')
139142
install.install.run(self)
140143

@@ -171,9 +174,10 @@ def is_excluded(s):
171174
paths.add(full_path)
172175
return list(paths)
173176

177+
174178
setup(
175179
name='dm_control',
176-
version='1.0.20',
180+
version='1.0.22',
177181
description='Continuous control environments and MuJoCo Python bindings.',
178182
long_description="""
179183
# `dm_control`: DeepMind Infrastructure for Physics-Based Simulation.
@@ -201,7 +205,7 @@ def is_excluded(s):
201205
'glfw',
202206
'labmaze',
203207
'lxml',
204-
'mujoco >= 3.1.6',
208+
'mujoco >= 3.2.1',
205209
'numpy >= 1.9.0',
206210
'protobuf >= 3.19.4', # TensorFlow requires protobuf<3.20 (b/182876485)
207211
'pyopengl >= 3.1.4',
@@ -222,17 +226,23 @@ def is_excluded(s):
222226
test_suite='nose.collector',
223227
packages=find_packages(),
224228
package_data={
225-
'dm_control':
226-
find_data_files(
227-
package_dir='dm_control',
228-
patterns=[
229-
'*.amc', '*.msh', '*.png', '*.skn', '*.stl', '*.xml',
230-
'*.textproto', '*.h5'
231-
],
232-
excludes=[
233-
'*/dog_assets/extras/*',
234-
'*/kinova/meshes/*', # Exclude non-decimated meshes.
235-
]),
229+
'dm_control': find_data_files(
230+
package_dir='dm_control',
231+
patterns=[
232+
'*.amc',
233+
'*.msh',
234+
'*.png',
235+
'*.skn',
236+
'*.stl',
237+
'*.xml',
238+
'*.textproto',
239+
'*.h5',
240+
],
241+
excludes=[
242+
'*/dog_assets/extras/*',
243+
'*/kinova/meshes/*', # Exclude non-decimated meshes.
244+
],
245+
),
236246
},
237247
cmdclass={
238248
'build_mjbindings': BuildMJBindingsCommand,

tutorial.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
"\"\"\")\n",
9494
"\n",
9595
"print('Installing dm_control...')\n",
96-
"!pip install -q dm_control\u003e=1.0.20\n",
96+
"!pip install -q dm_control\u003e=1.0.22\n",
9797
"\n",
9898
"# Configure dm_control to use the EGL rendering backend (requires GPU)\n",
9999
"%env MUJOCO_GL=egl\n",

0 commit comments

Comments
 (0)