Example #1
0
 def testEqualBroadcastingBounds(self):
     spec_1 = array_spec.BoundedArraySpec((1, 2),
                                          np.int32,
                                          minimum=0.0,
                                          maximum=1.0)
     spec_2 = array_spec.BoundedArraySpec((1, 2),
                                          np.int32,
                                          minimum=[0.0, 0.0],
                                          maximum=[1.0, 1.0])
     self.assertEqual(spec_1, spec_2)
Example #2
0
 def testNotEqualDifferentMaximum(self):
     spec_1 = array_spec.BoundedArraySpec((1, 2),
                                          np.int32,
                                          minimum=0.0,
                                          maximum=2.0)
     spec_2 = array_spec.BoundedArraySpec((1, 2),
                                          np.int32,
                                          minimum=[0.0, 0.0],
                                          maximum=[1.0, 1.0])
     self.assertNotEqual(spec_1, spec_2)
  def testScalarBounds(self):
    spec = array_spec.BoundedArraySpec((), np.float, minimum=0.0, maximum=1.0)

    self.assertIsInstance(spec.minimum, np.ndarray)
    self.assertIsInstance(spec.maximum, np.ndarray)

    # Sanity check that numpy compares correctly to a scalar for an empty shape.
    self.assertEqual(0.0, spec.minimum)
    self.assertEqual(1.0, spec.maximum)

    # Check that the spec doesn't fail its own input validation.
    _ = array_spec.BoundedArraySpec(
        spec.shape, spec.dtype, spec.minimum, spec.maximum)
Example #4
0
 def setUp(self):
     env = mock.MagicMock(spec=environment.Base)
     env.action_spec.return_value = specs.BoundedArraySpec(
         (1, ), np.float64, -1, 1)
     self.runtime = runtime.Runtime(env, mock.MagicMock())
     self.runtime._step = mock.MagicMock()
     self.runtime._step.return_value = False
 def testValidateBounds(self):
   spec = array_spec.BoundedArraySpec((2, 2), np.int32, minimum=5, maximum=10)
   spec.validate(np.array([[5, 6], [8, 10]], dtype=np.int32))
   with self.assertRaises(ValueError):
     spec.validate(np.array([[5, 6], [8, 11]], dtype=np.int32))
   with self.assertRaises(ValueError):
     spec.validate(np.array([[4, 6], [8, 10]], dtype=np.int32))
Example #6
0
 def testIsUnhashable(self):
     spec = array_spec.BoundedArraySpec(shape=(1, 2),
                                        dtype=np.int32,
                                        minimum=0.0,
                                        maximum=2.0)
     with six.assertRaisesRegex(self, TypeError, "unhashable type"):
         hash(spec)
Example #7
0
def _action_spec_from_action_space(action_space):
    if isinstance(action_space, gym.spaces.Box):
        spec = specs.BoundedArraySpec(shape=action_space.shape,
                                      dtype=action_space.dtype,
                                      minimum=action_space.low,
                                      maximum=action_space.high)
    elif isinstance(action_space, gym.spaces.Discrete):
        spec = specs.BoundedArraySpec(shape=(1, ),
                                      dtype=action_space.dtype,
                                      minimum=0,
                                      maximum=action_space.n)

    else:
        raise NotImplementedError(action_space)

    return spec
Example #8
0
 def testGenerateValue(self):
     spec = array_spec.BoundedArraySpec((2, 2),
                                        np.int32,
                                        minimum=5,
                                        maximum=10)
     test_value = spec.generate_value()
     spec.validate(test_value)
Example #9
0
 def testRepr(self):
     as_string = repr(
         array_spec.BoundedArraySpec((1, 2),
                                     np.int32,
                                     minimum=101.0,
                                     maximum=73.0))
     self.assertIn("101", as_string)
     self.assertIn("73", as_string)
Example #10
0
 def setUp(self):
     env = mock.MagicMock()
     env.action_spec.return_value = specs.BoundedArraySpec(
         (1, ), np.float64, -1, 1)
     self.runtime = runtime.Runtime(env, mock.MagicMock())
     self.runtime._start = mock.MagicMock()
     self.runtime.get_time = mock.MagicMock()
     self.runtime.get_time.return_value = 0
     self.runtime._step_simulation = mock.MagicMock(return_value=False)
Example #11
0
    def setUp(self):
        env = mock.MagicMock(spec=environment.Base)
        env.action_spec.return_value = specs.BoundedArraySpec(
            (1, ), np.float64, -1, 1)
        self.runtime = runtime.Runtime(env, mock.MagicMock())
        self.runtime._step_paused = mock.MagicMock()
        self.runtime._step = mock.MagicMock(return_value=True)
        self.runtime.get_time = mock.MagicMock(return_value=0)

        self.time_step = 1e-2
Example #12
0
 def setUp(self):
     self.observation = mock.MagicMock()
     self.env = mock.MagicMock(spec=environment.Base)
     self.env.physics = mock.MagicMock()
     self.env.step = mock.MagicMock()
     self.env.action_spec.return_value = specs.BoundedArraySpec(
         (1, ), np.float64, -1, 1)
     self.policy = mock.MagicMock()
     self.actions = mock.MagicMock()
     self.runtime = runtime.Runtime(self.env, self.policy)
Example #13
0
 def action_spec(self):
     minimum, maximum = zip(*[
         a.ctrlrange if a.ctrlrange is not None else (-1., 1.)
         for a in self.actuators
     ])
     return specs.BoundedArraySpec(
         shape=(len(self.actuators), ),
         dtype=np.float,
         minimum=minimum,
         maximum=maximum,
         name='\t'.join([actuator.name for actuator in self.actuators]))
Example #14
0
def action_spec(physics):
  """Returns a `BoundedArraySpec` matching the `physics` actuators."""
  num_actions = physics.model.nu
  is_limited = physics.model.actuator_ctrllimited.ravel().astype(np.bool)
  control_range = physics.model.actuator_ctrlrange
  minima = np.full(num_actions, fill_value=-np.inf, dtype=np.float)
  maxima = np.full(num_actions, fill_value=np.inf, dtype=np.float)
  minima[is_limited], maxima[is_limited] = control_range[is_limited].T

  return specs.BoundedArraySpec(
      shape=(num_actions,), dtype=np.float, minimum=minima, maximum=maxima)
Example #15
0
class DefaultActionFromSpecTest(parameterized.TestCase):
    def assertNestedArraysEqual(self, expected, actual):
        """Asserts that two potentially nested structures of arrays are equal."""
        if isinstance(expected, (list, tuple)):
            self.assertIsInstance(actual, (list, tuple))
            self.assertLen(actual, len(expected))
            for expected_item, actual_item in zip(expected, actual):
                self.assertNestedArraysEqual(expected_item, actual_item)
        else:
            np.testing.assert_array_equal(expected, actual)

    _SHAPE = (2, )
    _DTYPE = np.float64
    _ACTION = np.zeros(_SHAPE)
    _ACTION_SPEC = specs.BoundedArraySpec(_SHAPE, np.float64, -1, 1)

    @parameterized.named_parameters(
        ('single_array', _ACTION_SPEC, _ACTION),
        ('tuple', (_ACTION_SPEC, _ACTION_SPEC), (_ACTION, _ACTION)),
        ('list', [_ACTION_SPEC, _ACTION_SPEC], (_ACTION, _ACTION)))
    def test_action_structure(self, action_spec, expected_action):
        self.assertNestedArraysEqual(expected_action,
                                     runtime._get_default_action(action_spec))

    @parameterized.named_parameters(
        ('closed',
         specs.BoundedArraySpec(_SHAPE, _DTYPE, minimum=1., maximum=2.),
         np.full(_SHAPE, fill_value=1.5, dtype=_DTYPE)),
        ('left_open',
         specs.BoundedArraySpec(_SHAPE, _DTYPE, minimum=-np.inf, maximum=2.),
         np.full(_SHAPE, fill_value=2., dtype=_DTYPE)),
        ('right_open',
         specs.BoundedArraySpec(_SHAPE, _DTYPE, minimum=1., maximum=np.inf),
         np.full(_SHAPE, fill_value=1., dtype=_DTYPE)),
        ('unbounded',
         specs.BoundedArraySpec(
             _SHAPE, _DTYPE, minimum=-np.inf,
             maximum=np.inf), np.full(_SHAPE, fill_value=0., dtype=_DTYPE)))
    def test_action_spec_interval(self, action_spec, expected_action):
        self.assertNestedArraysEqual(expected_action,
                                     runtime._get_default_action(action_spec))
Example #16
0
    def discount_spec(self):
        """Describes the discount returned by the environment.

    By default this is assumed to be a single float between 0 and 1.

    Returns:
      An `ArraySpec`, or a nested dict, list or tuple of `ArraySpec`s.
    """
        return specs.BoundedArraySpec(shape=(),
                                      dtype=float,
                                      minimum=0.,
                                      maximum=1.,
                                      name='discount')
  def testNotEqualOtherClass(self):
    spec_1 = array_spec.BoundedArraySpec(
        (1, 2), np.int32, minimum=[0.0, -0.6], maximum=[1.0, 1.0])
    spec_2 = array_spec.ArraySpec((1, 2), np.int32)
    self.assertNotEqual(spec_1, spec_2)
    self.assertNotEqual(spec_2, spec_1)

    spec_2 = None
    self.assertNotEqual(spec_1, spec_2)
    self.assertNotEqual(spec_2, spec_1)

    spec_2 = ()
    self.assertNotEqual(spec_1, spec_2)
    self.assertNotEqual(spec_2, spec_1)
Example #18
0
    def setUp(self):
        with mock.patch(application.__name__ + '.gui'):
            self.app = application.Application()

        self.app._viewer = mock.MagicMock()
        self.app._keyboard_action = mock.MagicMock()

        self.environment = mock.MagicMock(spec=environment.Base)
        self.environment.action_spec.return_value = specs.BoundedArraySpec(
            (1, ), np.float64, -1, 1)
        self.environment.physics = mock.MagicMock()
        self.app._environment = self.environment
        self.agent = mock.MagicMock()
        self.loader = lambda: self.environment
Example #19
0
    def action_spec(self, physics):
        """Returns an `BoundedArraySpec` matching the `Physics` actuators.

    BoundedArraySpec.name should contain a tab-separated list of actuator names.
    When overloading this method, non-MuJoCo actuators should be added to the
    top of the list when possible, as a matter of convention.

    Args:
      physics: used to query actuator names in the model.
    """
        names = [
            physics.model.id2name(i, 'actuator') or str(i)
            for i in range(physics.model.nu)
        ]
        action_spec = mujoco.action_spec(physics)
        return specs.BoundedArraySpec(shape=action_spec.shape,
                                      dtype=action_spec.dtype,
                                      minimum=action_spec.minimum,
                                      maximum=action_spec.maximum,
                                      name='\t'.join(names))
Example #20
0
class DefaultActionFromSpecTest(parameterized.TestCase):

  def assertNestedArraysEqual(self, expected, actual):
    """Asserts that two potentially nested structures of arrays are equal."""
    self.assertIs(type(actual), type(expected))
    if isinstance(expected, (list, tuple)):
      self.assertIsInstance(actual, (list, tuple))
      self.assertLen(actual, len(expected))
      for expected_item, actual_item in zip(expected, actual):
        self.assertNestedArraysEqual(expected_item, actual_item)
    elif isinstance(expected, collections.MutableMapping):
      keys_type = list if isinstance(expected, collections.OrderedDict) else set
      self.assertEqual(keys_type(actual.keys()), keys_type(expected.keys()))
      for key, expected_value in six.iteritems(expected):
        self.assertNestedArraysEqual(actual[key], expected_value)
    else:
      np.testing.assert_array_equal(expected, actual)

  _SHAPE = (2,)
  _DTYPE = np.float64
  _ACTION = np.zeros(_SHAPE)
  _ACTION_SPEC = specs.BoundedArraySpec(_SHAPE, np.float64, -1, 1)

  @parameterized.named_parameters(
      ('single_array', _ACTION_SPEC, _ACTION),
      ('tuple', (_ACTION_SPEC, _ACTION_SPEC), (_ACTION, _ACTION)),
      ('list', [_ACTION_SPEC, _ACTION_SPEC], (_ACTION, _ACTION)),
      ('dict',
       {'a': _ACTION_SPEC, 'b': _ACTION_SPEC},
       {'a': _ACTION, 'b': _ACTION}),
      ('OrderedDict',
       collections.OrderedDict([('a', _ACTION_SPEC), ('b', _ACTION_SPEC)]),
       collections.OrderedDict([('a', _ACTION), ('b', _ACTION)])),
      )
  def test_action_structure(self, action_spec, expected_action):
    self.assertNestedArraysEqual(expected_action,
                                 runtime._get_default_action(action_spec))

  def test_ordered_dict_action_structure_with_bad_ordering(self):
    reversed_spec = collections.OrderedDict([('a', self._ACTION_SPEC),
                                             ('b', self._ACTION_SPEC)])
    expected_action = collections.OrderedDict([('b', self._ACTION),
                                               ('a', self._ACTION)])
    with six.assertRaisesRegex(self, AssertionError,
                               r"Lists differ: \['a', 'b'\] != \['b', 'a'\]"):
      self.assertNestedArraysEqual(expected_action,
                                   runtime._get_default_action(reversed_spec))

  @parameterized.named_parameters(
      ('closed',
       specs.BoundedArraySpec(_SHAPE, _DTYPE, minimum=1., maximum=2.),
       np.full(_SHAPE, fill_value=1.5, dtype=_DTYPE)),
      ('left_open',
       specs.BoundedArraySpec(_SHAPE, _DTYPE, minimum=-np.inf, maximum=2.),
       np.full(_SHAPE, fill_value=2., dtype=_DTYPE)),
      ('right_open',
       specs.BoundedArraySpec(_SHAPE, _DTYPE, minimum=1., maximum=np.inf),
       np.full(_SHAPE, fill_value=1., dtype=_DTYPE)),
      ('unbounded',
       specs.BoundedArraySpec(_SHAPE, _DTYPE, minimum=-np.inf, maximum=np.inf),
       np.full(_SHAPE, fill_value=0., dtype=_DTYPE)))
  def test_action_spec_interval(self, action_spec, expected_action):
    self.assertNestedArraysEqual(expected_action,
                                 runtime._get_default_action(action_spec))
Example #21
0
 def make_action_spec(self, lower=(-1., ), upper=(1., )):
     lower, upper = np.broadcast_arrays(lower, upper)
     return specs.BoundedArraySpec(shape=lower.shape,
                                   dtype=float,
                                   minimum=lower,
                                   maximum=upper)
Example #22
0
 def testNotWriteable(self):
     spec = array_spec.BoundedArraySpec((1, 2, 3), np.float32, 0, (5, 5, 5))
     with six.assertRaisesRegex(self, ValueError, "read-only"):
         spec.minimum[0] = -1
     with six.assertRaisesRegex(self, ValueError, "read-only"):
         spec.maximum[0] = 100
Example #23
0
 def testMinMaxAttributes(self):
     spec = array_spec.BoundedArraySpec((1, 2, 3), np.float32, 0, (5, 5, 5))
     self.assertEqual(type(spec.minimum), np.ndarray)
     self.assertEqual(type(spec.maximum), np.ndarray)
Example #24
0
 def testInvalidMaximum(self):
     with six.assertRaisesRegex(self, ValueError, "not compatible"):
         array_spec.BoundedArraySpec((3, 5), np.uint8, 0, (1, 1, 1))
Example #25
0
    def __enter__(self):
        """Allows the environment to be used in a with-statement context."""
        return self

    def __exit__(self, unused_exception_type, unused_exc_value,
                 unused_traceback):
        """Allows the environment to be used in a with-statement context."""
        self.close()


# A `StepType` enum can be safely cast to an array that conforms to this spec.
STEP_TYPE_SPEC = specs.BoundedArraySpec(shape=(),
                                        dtype=np.promote_types(
                                            np.min_scalar_type(min(StepType)),
                                            np.min_scalar_type(max(StepType))),
                                        minimum=min(StepType),
                                        maximum=max(StepType),
                                        name='step_type')


def make_step_spec(environment):
    """Returns a `TimeStep` describing the return values of an environment.

  Args:
    environment: An instance of `Base`.

  Returns:
    A `TimeStep` namedtuple. Each field contains an `ArraySpec`, or a nested
    dict, list or tuple of `ArraySpec`s that describe the corresponding field in
    the return values of `environment.reset()` and `environment.step()`.
 def testInvalidMinimum(self):
   with self.assertRaisesRegexp(ValueError, "not compatible"):
     array_spec.BoundedArraySpec((3, 5), np.uint8, (0, 0, 0), (1, 1))
Example #27
0
from absl.testing import absltest
from absl.testing import parameterized

from dm_control.rl import control

import mock
import numpy as np

from dm_control.rl import specs

_CONSTANT_REWARD_VALUE = 1.0
_CONSTANT_OBSERVATION = {'observations': np.asarray(_CONSTANT_REWARD_VALUE)}

_ACTION_SPEC = specs.BoundedArraySpec(shape=(1, ),
                                      dtype=np.float,
                                      minimum=0.0,
                                      maximum=1.0)
_OBSERVATION_SPEC = {'observations': specs.ArraySpec(shape=(), dtype=np.float)}


class EnvironmentTest(parameterized.TestCase):
    def setUp(self):
        self._task = mock.Mock(spec=control.Task)
        self._task.initialize_episode = mock.Mock()
        self._task.get_observation = mock.Mock(
            return_value=_CONSTANT_OBSERVATION)
        self._task.get_reward = mock.Mock(return_value=_CONSTANT_REWARD_VALUE)
        self._task.get_termination = mock.Mock(return_value=None)
        self._task.action_spec = mock.Mock(return_value=_ACTION_SPEC)
        self._task.observation_spec.side_effect = NotImplementedError()