예제 #1
0
    def _peek_obs(self):
        obs = None
        start_time = time.time()
        if not self.done:
            logger.debug("Peeking the client.")
            peek_message = "<Peek/>"
            comms.send_message(self.client_socket, peek_message.encode())
            obs = comms.recv_message(self.client_socket)
            info = comms.recv_message(self.client_socket).decode('utf-8')

            reply = comms.recv_message(self.client_socket)
            done, = struct.unpack('!b', reply)
            self.done = done == 1
            if obs is None or len(obs) == 0:
                if time.time() - start_time > MAX_WAIT:
                    self.client_socket.close()
                    self.client_socket = None
                    raise MissionInitException(
                        'too long waiting for first observation')
                time.sleep(0.1)
            if self.done:
                raise RuntimeError(
                    "Something went wrong resetting the environment! "
                    "`done` was true on first frame.")

        # See if there is an integrated port
        if self._is_interacting:
            port = self._find_server()
            self.integratedServerPort = port
            logger.warn("MineRL agent is public, connect on port {} with Minecraft 1.11".format(port))
            # Todo make a launch command.
            


        return self._process_observation(obs, info)
예제 #2
0
파일: core.py 프로젝트: skbly7/minerl
    def _peek_obs(self):
        obs = None
        start_time = time.time()
        if not self.done:
            logger.debug("Peeking the client.")
            peek_message = "<Peek/>"
            comms.send_message(self.client_socket, peek_message.encode())
            obs = comms.recv_message(self.client_socket)
            info = comms.recv_message(self.client_socket).decode('utf-8')

            reply = comms.recv_message(self.client_socket)
            done, = struct.unpack('!b', reply)
            self.done = done == 1
            if obs is None or len(obs) == 0:
                if time.time() - start_time > MAX_WAIT:
                    self.client_socket.close()
                    self.client_socket = None
                    raise MissionInitException(
                        'too long waiting for first observation')
                time.sleep(0.1)
            if self.done:
                raise RuntimeError(
                    "Something went wrong resetting the environment! "
                    "`done` was true on first frame.")

        return self._process_observation(obs, info)
예제 #3
0
파일: core.py 프로젝트: skbly7/minerl
    def _find_server(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((self.instance.host, self.instance.port))
        self._hello(sock)

        start_time = time.time()
        port = 0
        while port == 0:
            comms.send_message(sock, ("<Find>" + self._get_token() +
                                      "</Find>").encode())
            reply = comms.recv_message(sock)
            port, = struct.unpack('!I', reply)
            if port == 0:
                if time.time() - start_time > MAX_WAIT:
                    if self.client_socket:
                        self.client_socket.close()
                        self.client_socket = None
                    raise MissionInitException(
                        'too long finding mission to join')
                time.sleep(1)
        sock.close()
        # print("Found mission integrated server port " + str(port))
        self.integratedServerPort = port
        e = self.xml.find(self.ns + 'MinecraftServerConnection')
        if e is not None:
            e.attrib['port'] = str(self.integratedServerPort)
예제 #4
0
    def close(self):
        """gym api close"""
        if self.viewer is not None:
            self.viewer.close()
            self.viewer = None

        if self._already_closed:
            return
        try:
            # Purge last token from head node with <Close> message.
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect((self.instance.host, self.instance.port))
            self._hello(sock)

            comms.send_message(sock, ("<Close>" + self._get_token() +
                                      "</Close>").encode())
            reply = comms.recv_message(sock)
            ok, = struct.unpack('!I', reply)
            assert ok
            sock.close()
            self._already_closed = True
        except Exception as e:
            self._log_error(e)
        if self.client_socket:
            self.client_socket.close()
            self.client_socket = None

        if self.instance and self.instance.running:
            self.instance.kill()
예제 #5
0
    def step(self, action):

        withinfo = MineRLEnv.STEP_OPTIONS == 0 or MineRLEnv.STEP_OPTIONS == 2

        # Process the actions.
        malmo_command = self._process_action(action)
        try:
            if not self.done:

                step_message = "<Step" + str(MineRLEnv.STEP_OPTIONS) + ">" + \
                               malmo_command + \
                               "</Step" + str(MineRLEnv.STEP_OPTIONS) + " >"

                # Send Actions.
                comms.send_message(self.client_socket, step_message.encode())

                # Receive the observation.
                obs = comms.recv_message(self.client_socket)

                # Receive reward done and sent.
                reply = comms.recv_message(self.client_socket)
                reward, done, sent = struct.unpack('!dbb', reply)

                # Receive info from the environment.
                if withinfo:
                    info = comms.recv_message(
                        self.client_socket).decode('utf-8')
                else:
                    info = {}

                # Process the observation and done state.
                out_obs = self._process_observation(obs, info)
                self.done = (done == 1)

                if self._is_real_time:
                    t0 = time.time()
                    # Todo: Add catch-up
                    time.sleep(
                        max(0, TICK_LENGTH - (t0 - self._last_step_time)))
                    self._last_step_time = time.time()

                return out_obs, reward, self.done, {}
            else:
                raise RuntimeError(
                    "Attempted to step an environment with done=True")
        except (socket.timeout, socket.error) as e:
            # If the socket times out some how! We need to catch this and reset the environment.
            self._clean_connection()
            self.done = True
            logger.error(
                "Failed to take a step (timeout or error). Terminating episode and sending random observation, be aware. "
                "To account for this failure case in your code check to see if `'error' in info` where info is "
                "the info dictionary returned by the step function.")
            return self.observation_space.sample(), 0, self.done, {
                "error": "Connection timed out!"
            }
예제 #6
0
def request_interactor(instance, ip):
    sock = get_socket(instance)
    MineRLEnv._hello(sock)

    comms.send_message(sock,
        ("<Interact>" + ip + "</Interact>").encode())
    reply = comms.recv_message(sock)
    ok, = struct.unpack('!I', reply)
    if not ok:
        raise RuntimeError("Failed to start interactor")
    sock.close()
예제 #7
0
    def reinit(self):
        """Use carefully to reset the episode count to 0."""
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((self.instance.host, self.instance.port))
        self._hello(sock)

        comms.send_message(
            sock, ("<Init>" + self._get_token() + "</Init>").encode())
        reply = comms.recv_message(sock)
        sock.close()
        ok, = struct.unpack('!I', reply)
        return ok != 0
예제 #8
0
    def status(self):
        """Get status from server.
        head - Ping the the head node if True.
        """
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((self.instance.host, self.instance.port))

        self._hello(sock)

        comms.send_message(sock, "<Status/>".encode())
        status = comms.recv_message(sock).decode('utf-8')
        sock.close()
        return status
예제 #9
0
    def _find_server(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((self.instance.host, self.instance.port))
        self._hello(sock)

        start_time = time.time()
        port = 0
        while port == 0:
            comms.send_message(
                sock, ("<Find>" + self._get_token() + "</Find>").encode())
            reply = comms.recv_message(sock)
            port, = struct.unpack('!I', reply)
        sock.close()
        # print("Found mission integrated server port " + str(port))
        return  port
예제 #10
0
파일: malmo.py 프로젝트: curieuxjy/minerl
        def _kill_minecraft_via_malmoenv(host, port):
            """Use carefully to cause the Minecraft service to exit (and hopefully restart).
            """
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(1)
                sock.connect((host, port))
                comms.send_message(sock, ("<MalmoEnv" + malmo_version + "/>").encode())

                comms.send_message(sock, ("<Exit>NOW</Exit>").encode())
                reply = comms.recv_message(sock)
                ok, = struct.unpack('!I', reply)
                sock.close()
                return ok == 1
            except Exception as e:
                logger.error("Attempted to send kill command to minecraft process and failed.")
                return False
예제 #11
0
    def _init_mission(self):
        ok = 0
        num_retries = 0
        logger.debug("Sending mission init!")
        while ok != 1:
            xml = etree.tostring(self.xml)
            token = (self._get_token() + ":" + str(self.agent_count) + ":" +
                     str(self.synchronous).lower()).encode()
            comms.send_message(self.client_socket, xml)
            comms.send_message(self.client_socket, token)

            reply = comms.recv_message(self.client_socket)
            ok, = struct.unpack('!I', reply)
            if ok != 1:
                num_retries += 1
                if num_retries > MAX_WAIT:
                    raise socket.timeout()
                logger.debug("Recieved a MALMOBUSY from Malmo; trying again.")
                time.sleep(1)
예제 #12
0
 def _quit_episode(self):
     comms.send_message(self.client_socket, "<Quit/>".encode())
     reply = comms.recv_message(self.client_socket)
     ok, = struct.unpack('!I', reply)
     return ok != 0
예제 #13
0
 def _hello(sock):
     comms.send_message(sock, ("<MalmoEnv" + malmo_version + "/>").encode())
예제 #14
0
    def step(self, action):
        obs = None
        reward = None
        info = None
        turn = True
        withturnkey = self.step_options < 2
        # print(withturnkey)
        withinfo = self.step_options == 0 or self.step_options == 2

        malmo_command = self._process_action(action)

        try:
            if not self.done:

                step_message = "<Step" + str(self.step_options) + ">" + \
                            malmo_command + \
                            "</Step" + str(self.step_options) + " >"
                t0 = time.time()
                comms.send_message(self.client_socket, step_message.encode())
                # print("send action {}".format(time.time() - t0)); t0 = time.time()
                if withturnkey:
                    comms.send_message(self.client_socket,
                                       self.turn_key.encode())
                obs = comms.recv_message(self.client_socket)
                # print("recieve obs {}".format(time.time() - t0)); t0 = time.time()

                reply = comms.recv_message(self.client_socket)
                reward, done, sent = struct.unpack('!dbb', reply)
                # print("recieve reward {}".format(time.time() - t0)); t0 = time.time()
                self.done = done == 1
                if withinfo:
                    info = comms.recv_message(
                        self.client_socket).decode('utf-8')

                out_obs = self._process_observation(obs, info)

                turn_key = comms.recv_message(
                    self.client_socket).decode('utf-8') if withturnkey else ""
                # print("[" + str(self.role) + "] TK " + turn_key + " self.TK " + str(self.turn_key))
                if turn_key != "":
                    if sent != 0:
                        turn = False
                    # Done turns if: turn = self.turn_key == turn_key
                    self.turn_key = turn_key
                else:
                    turn = sent == 0

                # if (obs is None or len(obs) == 0) or turn:
                # time.sleep(0.1)
                # print("turnkeyprocessor {}".format(time.time() - t0)); t0 = time.time()
                # print("creating obs from buffer {}".format(time.time() - t0)); t0 = time.time()
                return out_obs, reward, self.done, {}
            else:
                raise RuntimeError(
                    "Attempted to step an environment with done=True")
        except socket.timeout as e:
            # If the socket times out some how! We need to catch this and reset the environment.
            self._clean_connection()
            self.done = True
            logger.error(
                "Failed to take a step (timeout). Terminating episode and sending random observation, be aware. "
                "To account for this failure case in your code check to see if `'error' in info` where info is "
                "the info dictionary returned by the step function.")
            return self.observation_space.sample(), 0, self.done, {
                "error": "Connection timed out!"
            }