Beispiel #1
0
    def __add__(self, other):
        """
        Combine two different states together. In this special case, the operation is not commutable.
        This is the same as taking the union of the states.

        Args:
            other (State): another state

        Returns:
            State: the combined state

        Examples:
            s1 = JntPositionState(robot)
            s2 = JntVelocityState(robot)
            s = s1 + s2     # = State([JntPositionState(robot), JntVelocityState(robot)])

            s1 = State([JntPositionState(robot), JntVelocityState(robot)])
            s2 = State([JntPositionState(robot), LinkPositionState(robot)])
            s = s1 + s2     # = State([JntPositionState(robot), JntVelocityState(robot), LinkPositionState(robot)])
        """
        if not isinstance(other, State):
            raise TypeError("Expecting another state, instead got {}".format(
                type(other)))
        s1 = self._states if self._data is None else OrderedSet([self])
        s2 = other._states if other._data is None else OrderedSet([other])
        s = s1 + s2
        return State(s)
Beispiel #2
0
    def __add__(self, other):
        """
        Combine two different actions together. In this special case, the operation is not commutable.
        This is the same as taking the union of the actions.

        Args:
            other (Action): another action

        Returns:
            Action: the combined action

        Examples:
            s1 = JntPositionAction(robot)
            s2 = JntVelocityAction(robot)
            s = s1 + s2     # = Action([JntPositionAction(robot), JntVelocityAction(robot)])

            s1 = Action([JntPositionAction(robot), JntVelocityAction(robot)])
            s2 = Action([JntPositionAction(robot), LinkPositionAction(robot)])
            s = s1 + s2     # = Action([JntPositionAction(robot), JntVelocityAction(robot), LinkPositionAction(robot)])
        """
        if not isinstance(other, Action):
            raise TypeError("Expecting another action, instead got {}".format(
                type(other)))
        s1 = self._actions if self._data is None else OrderedSet([self])
        s2 = other._actions if other._data is None else OrderedSet([other])
        s = s1 + s2
        return Action(s)
Beispiel #3
0
    def __sub__(self, other):
        """
        Remove the other state(s) from the current state.

        Args:
            other (State): state to be removed.
        """
        if not isinstance(other, State):
            raise TypeError("Expecting another state, instead got {}".format(
                type(other)))
        s1 = self._states if self._data is None else OrderedSet([self])
        s2 = other._states if other._data is None else OrderedSet([other])
        s = s1 - s2
        if len(s) == 1:  # just one element
            return s[0]
        return State(s)
Beispiel #4
0
    def __sub__(self, other):
        """
        Remove the other action(s) from the current action.

        Args:
            other (Action): action to be removed.
        """
        if not isinstance(other, Action):
            raise TypeError("Expecting another action, instead got {}".format(
                type(other)))
        s1 = self._actions if self._data is None else OrderedSet([self])
        s2 = other._actions if other._data is None else OrderedSet([other])
        s = s1 - s2
        if len(s) == 1:  # just one element
            return s[0]
        return Action(s)
Beispiel #5
0
    def __init__(self, actions=(), data=None, space=None, name=None, ticks=1):
        """
        Initialize the action. The action contains some kind of data, or is a combination of other actions.

        Args:
            actions (list/tuple of Action): list of actions to be combined together (if given, we can not specified
                                            data)
            data (np.ndarray): data associated to this action
            space (gym.space): space associated with the given data
            ticks (int): number of ticks to sleep before setting the next action data.

        Warning:
            Both arguments can not be provided to the action.
        """
        # Check arguments
        if actions is None:
            actions = tuple()

        if not isinstance(actions, (list, tuple, set, OrderedSet)):
            raise TypeError(
                "Expecting a list, tuple, or (ordered) set of actions.")
        if len(actions) > 0 and data is not None:
            raise ValueError(
                "Please specify only one of the argument `actions` xor `data`, but not both."
            )

        # Check if data is given
        if data is not None:
            if not isinstance(data, np.ndarray):
                if isinstance(data, (list, tuple)):
                    data = np.array(data)
                elif isinstance(data, (int, float)):
                    data = np.array([data])
                else:
                    raise TypeError(
                        "Expecting a numpy array, a list/tuple of int/float, or an int/float for 'data'"
                    )

        # The following attributes should normally be set in the child classes
        self._data = data
        self._torch_data = data if data is None else torch.from_numpy(
            data).float()
        self._space = space
        self._distribution = None  # for sampling
        self._normalizer = None
        self._noiser = None  # for noise
        self.name = name

        # create ordered set which is useful if this action is a combination of multiple actions
        self._actions = OrderedSet()
        if self._data is None:
            self.add(actions)

        # set ticks and counter
        self.cnt = 0
        self.ticks = int(ticks)
Beispiel #6
0
    def __isub__(self, other):
        """
        Remove one or several states from the combined state.

        Args:
            other (State): state to be removed.
        """
        if not isinstance(other, State):
            raise TypeError("Expecting another state, instead got {}".format(
                type(other)))
        if self._data is not None:
            raise RuntimeError(
                "This operation is only available for a combined state")
        s = other._states if other._data is None else OrderedSet([other])
        self._states -= s
Beispiel #7
0
    def __isub__(self, other):
        """
        Remove one or several actions from the combined action.

        Args:
            other (Action): action to be removed.
        """
        if not isinstance(other, Action):
            raise TypeError("Expecting another action, instead got {}".format(
                type(other)))
        if self._data is not None:
            raise RuntimeError(
                "This operation is only available for a combined action")
        s = other._actions if other._data is None else OrderedSet([other])
        self._actions -= s
Beispiel #8
0
    def __init__(self,
                 states=(),
                 data=None,
                 space=None,
                 window_size=1,
                 axis=None,
                 ticks=1,
                 name=None):
        """
        Initialize the state. The state contains some kind of data, or is a state combined of other states.

        Args:
            states (list/tuple of State): list of states to be combined together (if given, we can not specified data)
            data (np.array): data associated to this state
            space (gym.space): space associated with the given data
            window_size (int): window size of the state. This is the total number of states we should remember. That
                is, if the user wants to remember the current state :math:`s_t` and the previous state :math:`s_{t-1}`,
                the window size is 2. By default, the :attr:`window_size` is one which means we only remember the
                current state. The window size has to be bigger than 1. If it is below, it will be set automatically
                to 1. The :attr:`window_size` attribute is only valid when the state is not a combination of states,
                but is given some :attr:`data`.
            axis (int, None): axis to concatenate or stack the states in the current window. If you have a state with
                shape (n,), then if the axis is None (by default), it will just concatenate it such that resulting
                state has a shape (n*w,) where w is the window size. If the axis is an integer, then it will just stack
                the states in the specified axis. With the example, for axis=0, the resulting state has a shape of
                (w,n), and for axis=-1 or 1, it will have a shape of (n,w). The :attr:`axis` attribute is only when the
                state is not a combination of states, but is given some :attr:`data`.
            ticks (int): number of ticks to sleep before getting the next state data.
            name (str, None): name of the state. If None, by default, it will have the name of the class.

        Warning:
            Both arguments can not be provided to the state.
        """
        # Check arguments
        if states is None:
            states = tuple()

        # check that the given `states` is a list of states
        if not isinstance(states, (list, tuple, set, OrderedSet)):
            # TODO: should check that states is a list of state, however O(N)
            if data is None and isinstance(
                    states, np.ndarray
            ):  # this is in the case someone calls `State(data)`
                data = states
                states = tuple()
            else:
                raise TypeError(
                    "Expecting a list, tuple, or (ordered) set of states.")

        # check that the list of states and the data are not provided together
        if len(states) > 0 and data is not None:
            raise ValueError(
                "Please specify only one of the argument `states` xor `data`, but not both."
            )

        # Check if the data is given, and convert it to a numpy array if necessary
        if data is not None:
            if not isinstance(data, np.ndarray):
                if isinstance(data, (list, tuple)):
                    data = np.array(data)
                elif isinstance(data, (int, float)):
                    data = np.array([data])
                else:
                    raise TypeError(
                        "Expecting a numpy array, a list/tuple of int/float, or an int/float for 'data'"
                    )

        # The following attributes should normally be set in the child classes
        self._data = data
        self._torch_data = data if data is None else torch.from_numpy(
            data).float()
        self._space = space
        self._distribution = None  # for sampling
        self._normalizer = None
        self._noiser = None  # for noise
        self.name = name
        self._training_mode = False

        # create ordered set which is useful if this state is a combination of multiple states
        self._states = OrderedSet()
        if self._data is None:
            self.add(states)

        # set data windows
        self._window, self._torch_window = None, None
        self.window_size = window_size  # this initializes the windows (FIFO queues)
        self.axis = axis

        # set ticks and counter
        self._cnt = 0
        self.ticks = ticks

        # reset state
        self.reset()