def step(self, action):
        """Take a continous action in the environment.

        Args:
            action: An action to be taken in the environment.

        Returns:
            A numpy array with rgb/depth/rgbd encoding of the state observation.
            An integer with reward from the environment.
            A boolean flag which is true when an episode is complete.
            No info given for fair learning.
        """
        self.step_count += 1
        logger.info("Step count: {}".format(str(self.step_count)))

        assert action is not None, "Action cannot be None."
        assert isinstance(action,
                          (np.ndarray)), "Action type is not recognized."
        action = np.clip(action, self.action_limit[0], self.action_limit[1])

        if self._closed:
            raise GymException("The environment has been closed.")

        state, reward, done = self.secured_bridge.monolith_continous_perform_action(
            action, self._channel_type, self.algorithm_mode)

        self._last_state = state

        if done:
            logger.debug('Environment episode is complete.')
            self.step_count = 0
        logger.info('Environment step is complete.')
        return state, reward, done, {}
Пример #2
0
    def perform_handshake(self, experiment_name, resume_experiment,
                          learning_type, algorithm_mode, environment_name):
        """Perform handshake with the gym server.

        To perform a handshake: initiate communication with the server, 
        get the robot's heartbeat, send experiment details to the server.

        Args:
            experiment_name: String value as the experiment name.
            resume_experiment: Boolean value to indicate if existing experiment is to be resumed.
            learning_type: String value indicating whether type is end2end, humandemos or sim2real.

        Returns:
            A string value with the heartbeat status.
            A boolean value to indicate whether experiment was registered or not.
            A string containing message from the server.
        """

        # Initiate communication by sharing the api-token
        self._web_token = self._initiate_communication()

        # Get the heartbeat of the robot
        # Share the experiment details with the server
        req = SetUpRequest(self._web_token, experiment_name, resume_experiment,
                           learning_type, algorithm_mode, environment_name)
        api_endpoint = "https://{}:{}/{}".format(self._server_ip,
                                                 self._secured_port,
                                                 SetUpRequest.URI)

        set_up_response = None
        try:
            set_up_response = requests.post(url=api_endpoint,
                                            json=req.to_dict(),
                                            verify=self._certificate)
            set_up_response_json = json.loads(set_up_response.text)
        except (requests.exceptions.Timeout,
                requests.exceptions.ConnectionError) as err:
            raise GymException(f"A request error occurred:\n{err}")
        except Exception as err:
            if set_up_response is not None and set_up_response.status_code == HTTPStatus.NOT_FOUND:
                raise GymException(
                    "The robot is not available. The environment is possibly under MAINTENANCE."
                )
            elif set_up_response is not None and set_up_response.status_code == HTTPStatus.UNAUTHORIZED:
                raise GymException(
                    "Unauthorized. Most likely your time slot has ended. Please try again."
                )
            else:
                raise GymException(
                    f"A server error has occurred. Please contact the support team: [email protected].\n{err}"
                )
        logger.debug("Heartbeat  : {}".format(
            set_up_response_json['heartbeat']))
        self._web_token = set_up_response_json['web_token']

        return set_up_response_json['heartbeat'], set_up_response_json[
            'registered'], set_up_response_json['message']
Пример #3
0
    def monolith_continous_perform_reset(self,
                                         channel_type=Channels.DEPTH_ONLY):
        """Requests server to reset the environment.

        Args:
            channel_type: Channels type value, determines observation's channel.

        Returns:
            A numpy array as the observation.
        """
        logger.debug("Waiting for reset done from the server.")

        req = MonolithDiscreteResetRequest(self._web_token,
                                           channel_type=channel_type)
        api_endpoint = "https://{}:{}/{}".format(
            self._server_ip, self._secured_port,
            MonolithDiscreteResetRequest.URI)

        response = None
        try:
            response = requests.post(url=api_endpoint,
                                     json=req.to_dict(),
                                     verify=self._certificate)
            response_json = json.loads(response.text)
            state = json.loads(response_json['state'])

        except (requests.exceptions.Timeout,
                requests.exceptions.ConnectionError) as err:
            raise GymException(f"A request error occurred:\n{err}")

        except Exception as err:
            if response is not None and response.status_code == HTTPStatus.NOT_FOUND:
                raise GymException(
                    "The robot is not available. The environment is possibly under MAINTENANCE."
                )
            elif response is not None and response.status_code == HTTPStatus.UNAUTHORIZED:
                raise GymException(
                    "Unauthorized. Most likely your time slot has ended. Please try again."
                )
            else:
                raise GymException(
                    f"A server error has occurred. Please contact the support team: [email protected].\n{err}"
                )

        state = np.asarray(state)
        state = np.reshape(state,
                           (1, state.shape[0], state.shape[1], state.shape[2]))
        logger.debug('Environment reset done. The state shape is: ' +
                     str(state.shape))

        self._web_token = response_json['web_token']

        return state
Пример #4
0
    def _initiate_communication(self):
        """Validate api token, get web token for next request.

        Validates the api-token of an user and checks if user has access to the environment.
        """

        token_var = self.settings_dict["user"]["api_token"]
        if not token_var in os.environ:
            raise ValueError(
                "Please update OFFWORLD_GYM_ACCESS_TOKEN environment variable with api-token."
            )

        if os.environ[token_var] is None or os.environ[token_var] == '':
            raise ValueError("Api-token is null or empty.")

        req = TokenRequest(os.environ[token_var])
        api_endpoint = "https://{}:{}/{}".format(self._server_ip,
                                                 self._secured_port,
                                                 TokenRequest.URI)
        response = None
        try:
            response = requests.post(url=api_endpoint,
                                     json=req.to_dict(),
                                     verify=self._certificate)
            response_json = json.loads(response.text)
        except (requests.exceptions.Timeout,
                requests.exceptions.ConnectionError) as err:
            raise GymException(f"A request error occurred:\n{err}")
        except Exception as err:
            if response is not None and response.status_code == HTTPStatus.NOT_FOUND:
                raise GymException(
                    "The robot is not available. The environment is possibly under MAINTENANCE."
                )
            elif response is not None and response.status_code == HTTPStatus.UNAUTHORIZED:
                raise GymException(
                    "Unauthorized. Most likely your time slot has ended. Please try again."
                )
            else:
                raise GymException(
                    f"A server error has occurred. Please contact the support team: [email protected].\n{err}"
                )
        logger.debug("Web Token  : {}".format(response_json['web_token']))
        return response_json['web_token']
    def step(self, action):
        """Take a discrete action in the environment.

        Args:
            action: An action to be taken in the environment.

        Returns:
            A numpy array with rgb/depth/rgbd encoding of the state observation.
            An integer with reward from the environment.
            A boolean flag which is true when an episode is complete.
            No info given for fair learning.
        """
        self.step_count += 1
        logger.info("Step count: {}".format(str(self.step_count)))

        assert action is not None, "Action cannot be None."

        # convert float if it's exactly an integer value, otherwise let it throw an error
        if isinstance(
                action,
            (float, np.float32, np.float64)) and float(action).is_integer():
            action = int(action)

        assert isinstance(action, (FourDiscreteMotionActions, int, np.int32,
                                   np.int64)), "Action type is not recognized."

        if self._closed:
            raise GymException("The environment has been closed.")

        if isinstance(action, (int, np.int32, np.int64)):
            assert action >= 0 and action < 4, "Unrecognized value for the action"
            action = FourDiscreteMotionActions(action)

        state, reward, done = self.secured_bridge.monolith_discrete_perform_action(
            action, self._channel_type, self.algorithm_mode)

        self._last_state = state

        if done:
            logger.debug('Environment episode is complete.')
            self.step_count = 0
        logger.info('Environment step is complete.')
        return state, reward, done, {}
Пример #6
0
    def disconnect(self, channel_type, discrete=True):
        """Disconnect from the backend.
        """
        logger.debug("Disconnecting from the server.")

        uri = DisconnectRequest.URI_DISCRETE if discrete else DisconnectRequest.URI_CONTINOUS
        req = DisconnectRequest(self._web_token, channel_type=channel_type)
        api_endpoint = "https://{}:{}/{}".format(self._server_ip,
                                                 self._secured_port, uri)
        try:
            response = requests.post(url=api_endpoint,
                                     json=req.to_dict(),
                                     verify=self._certificate)
        except (requests.exceptions.Timeout,
                requests.exceptions.ConnectionError) as err:
            raise GymException(f"A request error occurred:\n{err}")
        except Exception as err:
            raise GymException(
                f"A server error has occurred. Please contact the support team: [email protected].\n{err}"
            )
Пример #7
0
    def monolith_continous_perform_action(self, action, channel_type,
                                          algorithm_mode):
        """Perform an action on the robot

        Args:
            action: Two dimensional action value with the action to execute.
            channel_type: Channels type value, determines observation's channel.
            algorithm_mode: Whether algorithm is being run in train or test modde.

        Returns:
            A numpy array as the observation.
            An integer value represeting reward from the environment.
            A boolean value that indicates whether episode is done or not.
        """
        start_time = time.time()
        self._action_counter += 1
        logger.debug("Start executing action {}, count : {}.".format(
            np.array2string(action), str(self._action_counter)))

        req = MonolithContinousActionRequest(self._web_token,
                                             action=action.tolist(),
                                             channel_type=channel_type,
                                             algorithm_mode=algorithm_mode)
        api_endpoint = "https://{}:{}/{}".format(
            self._server_ip, self._secured_port,
            MonolithContinousActionRequest.URI)

        response = None
        try:
            response = requests.post(url=api_endpoint,
                                     json=req.to_dict(),
                                     verify=self._certificate)
            response_json = json.loads(response.text)
            reward = int(response_json['reward'])
            state = json.loads(response_json['state'])
            done = bool(response_json['done'])
        except (requests.exceptions.Timeout,
                requests.exceptions.ConnectionError) as err:
            raise GymException(f"A request error occurred:\n{err}")
        except Exception as err:
            if response is not None and response.status_code == HTTPStatus.NOT_FOUND:
                raise GymException(
                    "The robot is not available. The environment is possibly under MAINTENANCE."
                )
            elif response is not None and response.status_code == HTTPStatus.UNAUTHORIZED:
                raise GymException(
                    "Unauthorized. Most likely your time slot has ended. Please try again."
                )
            else:
                raise GymException(
                    f"A server error has occurred. Please contact the support team: [email protected].\n{err}"
                )

        if 'testing' in response_json:
            raise GymException(response_json["message"])

        state = np.asarray(state)
        state = np.reshape(state,
                           (1, state.shape[0], state.shape[1], state.shape[2]))

        logger.debug("Reward  : {}".format(str(reward)))
        logger.debug("Is done : {}".format(str(done)))

        self._web_token = response_json['web_token']
        logger.debug(
            "Action execution complete. Telemetry recieved. Total time to execute: {}."
            .format(str(time.time() - start_time)))

        return state, reward, done