예제 #1
0
 def env(self):
     ps = DummyPhysicalSystem()
     rg = DummyReferenceGenerator()
     rf = DummyRewardFunction()
     vs = DummyVisualization()
     env = self.test_class(physical_system=ps,
                           reference_generator=rg,
                           reward_function=rf,
                           visualization=vs)
     return env
예제 #2
0
 def test_limits(self, number_states, state_filter, expected_result):
     ps = DummyPhysicalSystem(state_length=number_states)
     rg = DummyReferenceGenerator()
     rf = DummyRewardFunction()
     vs = DummyVisualization()
     env = self.test_class(physical_system=ps,
                           reference_generator=rg,
                           reward_function=rf,
                           visualization=vs,
                           state_filter=state_filter)
     assert all(env.limits == expected_result)
예제 #3
0
 def env(self):
     ps = DummyPhysicalSystem()
     rg = DummyReferenceGenerator()
     rf = DummyRewardFunction()
     vs = ()
     cb = DummyCallback()
     cm = DummyConstraintMonitor(2)
     env = self.test_class(physical_system=ps,
                           reference_generator=rg,
                           reward_function=rf,
                           visualization=vs,
                           constraints=cm,
                           callbacks=[cb])
     return env
예제 #4
0
class TestElectricMotorEnvironment:
    test_class = ElectricMotorEnvironment
    key = ''

    @pytest.fixture
    def env(self):
        ps = DummyPhysicalSystem()
        rg = DummyReferenceGenerator()
        rf = DummyRewardFunction()
        vs = DummyVisualization()
        cb = DummyCallback()
        env = self.test_class(physical_system=ps,
                              reference_generator=rg,
                              reward_function=rf,
                              visualization=vs,
                              callbacks=[cb])
        return env

    def test_make(self):
        if self.key != '':
            env = gem.make(self.key)
            assert type(env) == self.test_class

    @pytest.mark.parametrize(
        "physical_system, reference_generator, reward_function, state_filter, visualization, callbacks, kwargs",
        [
            (DummyPhysicalSystem, DummyReferenceGenerator, DummyRewardFunction,
             None, None, [], {}),
            (DummyPhysicalSystem(2), DummyReferenceGenerator,
             DummyRewardFunction(), ['dummy_state_0'
                                     ], ConsolePrinter, [DummyCallback()], {
                                         'a': 1,
                                         'b': 2
                                     }),
            (DummyPhysicalSystem(10), DummyReferenceGenerator(),
             DummyRewardFunction(observed_states=['dummy_state_0']), [
                 'dummy_state_0', 'dummy_state_2'
             ], None, [DummyCallback(), DummyCallback()], {}),
        ])
    def test_initialization(self, monkeypatch, physical_system,
                            reference_generator, reward_function, state_filter,
                            visualization, callbacks, kwargs):
        with monkeypatch.context() as m:
            instantiate_dict.clear()
            m.setattr(gym_electric_motor.core, "instantiate", mock_instantiate)
            env = gym_electric_motor.core.ElectricMotorEnvironment(
                physical_system=physical_system,
                reference_generator=reference_generator,
                reward_function=reward_function,
                visualization=visualization,
                state_filter=state_filter,
                callbacks=callbacks,
                **kwargs)

        # Assertions that the Keys are passed correctly to the instantiate fct
        assert physical_system == instantiate_dict[PhysicalSystem]['key']
        assert reference_generator == instantiate_dict[ReferenceGenerator][
            'key']
        assert reward_function == instantiate_dict[RewardFunction]['key']

        # Assertions that the modules that the instantiate functions returns are set correctly to the properties
        assert env.physical_system == instantiate_dict[PhysicalSystem][
            'instance']
        assert env.reference_generator == instantiate_dict[ReferenceGenerator][
            'instance']
        assert env.reward_function == instantiate_dict[RewardFunction][
            'instance']

        # Assertions for correct spaces
        assert env.action_space == instantiate_dict[PhysicalSystem][
            'instance'].action_space, 'Wrong action space'
        if state_filter is None:
            assert Tuple(
                (instantiate_dict[PhysicalSystem]['instance'].state_space,
                 instantiate_dict[ReferenceGenerator]['instance'].reference_space)) \
                   == env.observation_space, 'Wrong observation space'
        else:
            state_idxs = np.isin(physical_system.state_names, state_filter)
            state_space = Box(
                instantiate_dict[PhysicalSystem]
                ['instance'].state_space.low[state_idxs],
                instantiate_dict[PhysicalSystem]
                ['instance'].state_space.high[state_idxs],
            )
            assert Tuple(
                (state_space, instantiate_dict[ReferenceGenerator]
                 ['instance'].reference_space
                 )) == env.observation_space, 'Wrong observation space'
        assert env.reward_range == instantiate_dict[RewardFunction][
            'instance'].reward_range, 'Wrong reward range'

        # Test Correct passing of kwargs
        assert physical_system != DummyPhysicalSystem or env.physical_system.kwargs == kwargs
        assert reference_generator, DummyReferenceGenerator or env.reference_generator.kwargs == kwargs
        assert reward_function != DummyRewardFunction or env.reward_function.kwargs == kwargs
        assert visualization != DummyVisualization or env._visualization.kwargs == kwargs
        for callback in callbacks:
            assert callback._env == env

    def test_reset(self, env):
        ps = env.physical_system
        rg = env.reference_generator
        rf = env.reward_function
        vs = env._visualization
        cbs = env._callbacks
        rf.last_state = rf.last_reference = ps.state = rg.get_reference_state = vs.reference_trajectory = None
        # Initial amount of resets
        for callback in cbs:
            assert callback.reset_begin == 0
            assert callback.reset_end == 0
        state, ref = env.reset()
        # The corresponding callback functions should've been called
        for callback in cbs:
            assert callback.reset_begin == 1
            assert callback.reset_end == 1
        assert (
            state, ref
        ) in env.observation_space, 'Returned values not in observation space'
        assert np.all(np.all(state == ps.state)
                      ), 'Returned state is not the physical systems state'
        assert np.all(
            ref == rg.reference_observation
        ), 'Returned reference is not the reference generators reference'
        assert np.all(state == rg.get_reference_state
                      ), 'Incorrect state passed to the reference generator'
        assert rf.last_state == state, 'Incorrect state passed to the Reward Function'
        assert rf.last_reference == rg.reference_array, 'Incorrect Reference passed to the reward function'

    @pytest.mark.parametrize('action, set_done', [(0, False), (-1, False),
                                                  (1, False), (2, True)])
    def test_step(self, env, action, set_done):
        ps = env.physical_system
        rg = env.reference_generator
        rf = env.reward_function
        cbs = env._callbacks

        rf.set_done(set_done)
        with pytest.raises(Exception):
            env.step(
                action
            ), 'Environment goes through the step without previous reset'
        env.reset()
        # Callback's step inital step values
        for callback in cbs:
            assert callback.step_begin == 0
            assert callback.step_end == 0
        (state, reference), reward, done, _ = env.step(action)
        # Each of callback's step functions were called in step
        for callback in cbs:
            assert callback.step_begin == 1
            assert callback.step_end == 1
        assert np.all(
            state == ps.state[env.state_filter]
        ), 'Returned state and Physical Systems state are not equal'
        assert rg.get_reference_state == ps.state,\
            'State passed to the Reference Generator not equal to Physical System state'
        assert rg.get_reference_obs_state == ps.state, \
            'State passed to the Reference Generator not equal to Physical System state'
        assert ps.action == action, 'Action passed to Physical System not equal to selected action'
        assert reward == -1 if set_done else 1
        assert done == set_done
        # If episode terminated, no further step without reset
        if set_done:
            with pytest.raises(Exception):
                env.step(action)

    def test_close(self, env):
        ps = env.physical_system
        rg = env.reference_generator
        rf = env.reward_function
        vs = env._visualization
        cbs = env._callbacks
        # Callback's step inital close value
        for callback in cbs:
            assert callback.close == 0
        env.close()
        # Callback's close function was called on close
        for callback in cbs:
            assert callback.close == 1
        assert ps.closed, 'Physical System was not closed'
        assert rf.closed, 'Reward Function was not closed'
        assert rg.closed, 'Reference Generator was not closed'
        assert vs.closed, 'Visualization was not closed'

    @pytest.mark.parametrize("reference_generator",
                             (DummyReferenceGenerator(), ))
    def test_reference_generator_change(self, env, reference_generator):
        env.reset()
        env.reference_generator = reference_generator
        assert env.reference_generator == reference_generator, 'Reference Generator was not changed'
        # Without Reset an Exception has to be thrown
        with pytest.raises(Exception):
            env.step(env.action_space.sample(
            )), 'After Reference Generator change was no reset required'
        env.reset()
        # No Exception raised
        env.step(env.action_space.sample())

    @pytest.mark.parametrize("reward_function", (DummyRewardFunction(), ))
    def test_reward_function_change(self, env, reward_function):
        env.reset()
        reward_function.set_modules(
            physical_system=env.physical_system,
            reference_generator=env.reference_generator)
        env.reward_function = reward_function
        assert env.reward_function == reward_function, 'Reward Function was not changed'
        # Without Reset an Exception has to be thrown
        with pytest.raises(Exception):
            env.step(env.action_space.sample()
                     ), 'After Reward Function change was no reset required'
        env.reset()
        # No Exception raised
        env.step(env.action_space.sample())

    @pytest.mark.parametrize(
        "number_states, state_filter, expected_result",
        ((1, ['dummy_state_0'], [10]),
         (3, ['dummy_state_0', 'dummy_state_1', 'dummy_state_2'
              ], [10, 20, 30]), (3, ['dummy_state_1'], [20])))
    def test_limits(self, number_states, state_filter, expected_result):
        ps = DummyPhysicalSystem(state_length=number_states)
        rg = DummyReferenceGenerator()
        rf = DummyRewardFunction()
        vs = DummyVisualization()
        env = self.test_class(physical_system=ps,
                              reference_generator=rg,
                              reward_function=rf,
                              visualization=vs,
                              state_filter=state_filter)
        assert all(env.limits == expected_result)