# Path: HDPy/rl.py
# class Plant(object):
#     """A template for Actor-Critic *plants*. The *Plant* describes the
#     interaction of the Actor-Critic with the environment. Given a robot
#     which follows a certain *Policy*, the environment generates rewards
#     and robot states.
#     
#     An additional instance to :py:class:`PuPy.Normalization` may be 
#     supplied in ``norm`` for normalizing sensor values.
#     """
#     def __init__(self, state_space_dim=None, norm=None):
#         self._state_space_dim = state_space_dim
#         self.normalization = None
#         self.set_normalization(norm)
#     
#     def state_input(self, state):
#         """Return the state-part of the critic input
#         (i.e. the reservoir input).
#         
#         The state-part is derived from the current robot ``state`` and
#         possibly also its ``action``. As return format, a Nx1 numpy
#         vector is expected, where 2 dimensions should exist (e.g.
#         :py:meth:`numpy.atleast_2d`).
#         
#         Although the reservoir input will consist of both, the *state*
#         and *action*, this method must only return the *state* part of
#         it.
#         
#         """
#         raise NotImplementedError()
#     
#     def reward(self, epoch):
#         """A reward generated by the *Plant* based on the current
#         sensor readings in ``epoch``. The reward is single-dimensional.
#         
#         The reward is evaluated in every step. It builds the foundation
#         of the approximated return.
#         """
#         raise NotImplementedError()
#     
#     def state_space_dim(self):
#         """Return the dimension of the state space.
#         This value is equal to the size of the vector returned by
#         :py:meth:`state_input`.
#         """
#         if self._state_space_dim is None:
#             raise NotImplementedError()
#         return self._state_space_dim
#     
#     def set_normalization(self, norm):
#         """Set the normalization instance to ``norm``."""
#         if norm is None:
#             norm = PuPy.Normalization()
#         self.normalization = norm
#     
#     def reset(self):
#         """Reset plant to initial state."""
#         pass


from ...rl import Plant
import warnings
import numpy as np
        return ret

class CollisionAvoidanceSideways(Plant):
    """Plant for ePuck to realize collision avoidance. The state
    consists of the frontal and two sideways infrared sensors. The
    reward is negative, if one of those sensors reads a proximity
    lower than ``theta``. Gaussian noise is added to the reward if
    ``obs_noise`` is positive.
    
    """
    def __init__(self, theta, obs_noise=0.0):
        super(CollisionAvoidanceSideways, self).__init__(state_space_dim=3)
        self.theta = float(theta)
        self.obs_sigma = abs(float(obs_noise))
    
    def state_input(self, state):
        """Return the state from observations ``state``"""
        input_ = np.array((state['ir'][0, 0], state['ir'][0, 2], state['ir'][0, 6]))
        input_ = self.normalization.normalize_value('ir', input_)
        #input_ += np.random.normal(scale=0.001, size=input_.shape) # Additive noise
        return np.atleast_2d(input_).T
    
    def reward(self, epoch):
        """Return the reward produced by ``epoch``."""
        sensors = np.array((epoch['ir'][0, 0], epoch['ir'][0, 2], epoch['ir'][0, 6]))
        ret = float(sum([min(ir - self.theta, 0) for ir in sensors]))
        if self.obs_sigma > 0.0:
            ret += np.random.normal(scale=self.obs_sigma)
        return ret


# Path: HDPy/rl.py
# class Plant(object):
#     """A template for Actor-Critic *plants*. The *Plant* describes the
#     interaction of the Actor-Critic with the environment. Given a robot
#     which follows a certain *Policy*, the environment generates rewards
#     and robot states.
#     
#     An additional instance to :py:class:`PuPy.Normalization` may be 
#     supplied in ``norm`` for normalizing sensor values.
#     """
#     def __init__(self, state_space_dim=None, norm=None):
#         self._state_space_dim = state_space_dim
#         self.normalization = None
#         self.set_normalization(norm)
#     
#     def state_input(self, state):
#         """Return the state-part of the critic input
#         (i.e. the reservoir input).
#         
#         The state-part is derived from the current robot ``state`` and
#         possibly also its ``action``. As return format, a Nx1 numpy
#         vector is expected, where 2 dimensions should exist (e.g.
#         :py:meth:`numpy.atleast_2d`).
#         
#         Although the reservoir input will consist of both, the *state*
#         and *action*, this method must only return the *state* part of
#         it.
#         
#         """
#         raise NotImplementedError()
#     
#     def reward(self, epoch):
#         """A reward generated by the *Plant* based on the current
#         sensor readings in ``epoch``. The reward is single-dimensional.
#         
#         The reward is evaluated in every step. It builds the foundation
#         of the approximated return.
#         """
#         raise NotImplementedError()
#     
#     def state_space_dim(self):
#         """Return the dimension of the state space.
#         This value is equal to the size of the vector returned by
#         :py:meth:`state_input`.
#         """
#         if self._state_space_dim is None:
#             raise NotImplementedError()
#         return self._state_space_dim
#     
#     def set_normalization(self, norm):
#         """Set the normalization instance to ``norm``."""
#         if norm is None:
#             norm = PuPy.Normalization()
#         self.normalization = norm
#     
#     def reset(self):
#         """Reset plant to initial state."""
#         pass


# Path: HDPy/epuck/plant/plants.py
from ...rl import Plant
import warnings
import numpy as np

        return ret

class CollisionAvoidanceSideways(Plant):
    """Plant for ePuck to realize collision avoidance. The state
    consists of the frontal and two sideways infrared sensors. The
    reward is negative, if one of those sensors reads a proximity
    lower than ``theta``. Gaussian noise is added to the reward if
    ``obs_noise`` is positive.
    
    """
    def __init__(self, theta, obs_noise=0.0):
        super(CollisionAvoidanceSideways, self).__init__(state_space_dim=3)
        self.theta = float(theta)
        self.obs_sigma = abs(float(obs_noise))
    
    def state_input(self, state):
        """Return the state from observations ``state``"""
        input_ = np.array((state['ir'][0, 0], state['ir'][0, 2], state['ir'][0, 6]))
        input_ = self.normalization.normalize_value('ir', input_)
        #input_ += np.random.normal(scale=0.001, size=input_.shape) # Additive noise
        return np.atleast_2d(input_).T
    
    def reward(self, epoch):
        """Return the reward produced by ``epoch``."""
        sensors = np.array((epoch['ir'][0, 0], epoch['ir'][0, 2], epoch['ir'][0, 6]))
        ret = float(sum([min(ir - self.theta, 0) for ir in sensors]))
        if self.obs_sigma > 0.0:
            ret += np.random.normal(scale=self.obs_sigma)
        return ret


class CollisionAvoidanceFull(Plant):