Exemplo n.º 1
0
def run_interactor(ip, port, interactor_port=INTERACTOR_PORT):
    try:
        InstanceManager.add_existing_instance(interactor_port)
        instance = InstanceManager.get_instance(-1)
        print(instance)
    except AssertionError as e:
        logger.warning("No existing interactor found on port {}. Starting a new interactor.".format(interactor_port))
        instance = InstanceManager.Instance(interactor_port)
        instance.launch(daemonize=True)
    
    request_interactor(
        instance, '{}:{}'.format(ip, port)
    )
Exemplo n.º 2
0
    def _get_new_instance(self, port=None, instance_id=None):
        """
        Gets a new instance and sets up a logger if need be. 
        """

        if not port is None:
            instance = InstanceManager.add_existing_instance(port)
        else:
            instance = InstanceManager.get_instance(os.getpid(), instance_id=instance_id)

        if InstanceManager.is_remote():
            launch_queue_logger_thread(instance, self.is_closed)

        instance.launch()
        return instance
Exemplo n.º 3
0
 def _clean_connection(self):
     self.client_socket.shutdown(socket.SHUT_RDWR)
     self.client_socket.close()
     self.client_socket = None
     if self.had_to_clean:
         # Connect to a new instance!!
         logger.error(
             "Connection with Minecraft client cleaned more than once; restarting."
         )
         if self.instance:
             self.instance.kill()
         self.instance = InstanceManager.get_instance().__enter__()
         self.had_to_clean = False
     else:
         self.had_to_clean = True
Exemplo n.º 4
0
    def _clean_connection(self):
        logger.error("Cleaning connection! Something must have gone wrong.")
        try:
            if self.client_socket:
                self.client_socket.shutdown(socket.SHUT_RDWR)
                self.client_socket.close()
        except (BrokenPipeError, OSError, socket.error):
            # There is no connection left!
            pass

        self.client_socket = None
        if self.had_to_clean:
            # Connect to a new instance!!
            logger.error(
                "Connection with Minecraft client cleaned more than once; restarting."
            )
            if self.instance:
                self.instance.kill()
            self.instance = InstanceManager.get_instance()
            self.had_to_clean = False
        else:
            self.had_to_clean = True
Exemplo n.º 5
0
    def init(self, observation_space, action_space, port=None):
        """Initializes the MineRL Environment.

        Note: 
            This is called automatically when the environment is made.
        
        Args:
            observation_space (gym.Space): The observation for the environment.
            action_space (gym.Space): The action space for the environment.
            port (int, optional): The port of an exisitng Malmo environment. Defaults to None.
        
        Raises:
            EnvException: If the Mission XML is malformed this is thrown.
            ValueError: The space specified for this environment does not have a default action.
            NotImplementedError: When multiagent environments are attempted to be used.
        """
        step_options = 0
        resync = 0
        episode = 0
        exp_uid = None
        if self.instance == None:
            if not port is None:
                self.instance = InstanceManager.add_existing_instance(port)
            else:
                self.instance = InstanceManager.get_instance().__enter__()
        # Parse XML file
        with open(self.xml_file, 'r') as f:
            xml_text = f.read()
        xml = xml_text.replace('$(MISSIONS_DIR)', missions_dir)

        # Bootstrap the environment if it hasn't been.
        role = 0

        if not xml.startswith('<Mission'):
            i = xml.index("<Mission")
            if i == -1:
                raise EnvException("Mission xml must contain <Mission> tag.")
            xml = xml[i:]

        self.xml = etree.fromstring(xml)
        self.role = role
        if exp_uid is None:
            self.exp_uid = str(uuid.uuid4())
        else:
            self.exp_uid = exp_uid

        self.action_space = action_space
        self.observation_space = observation_space

        def map_space(space):
            if isinstance(space, gym.spaces.Discrete) or isinstance(
                    space, minerl.env.spaces.Enum):
                return 0
            elif isinstance(space, gym.spaces.Box):
                return np.zeros(shape=space.shape, dtype=space.dtype)
            else:
                try:
                    return space.default()
                except NameError:
                    raise ValueError(
                        'Specify non-None default_action in gym.register or extend all action spaces with default() method'
                    )

        if self._default_action is None:
            self._default_action = {
                key: map_space(space)
                for key, space in action_space.spaces.items()
            }

        def noop_func(a):
            return deepcopy(self._default_action)

        boundmethd = _bind(self.action_space, noop_func)
        self.action_space.noop = boundmethd

        # Force single agent
        self.agent_count = 1
        turn_based = self.xml.find('.//' + self.ns +
                                   'TurnBasedCommands') is not None
        if turn_based:
            raise NotImplementedError(
                "Turn based or multi-agent environments not supported.")
        else:
            self.turn_key = ""

        # Unclear what step_options does.
        if step_options is None:
            self.step_options = 0 if not turn_based else 2
        else:
            self.step_options = step_options

        self.done = True

        self.resync_period = resync
        self.resets = episode

        e = etree.fromstring(
            """<MissionInit xmlns="http://ProjectMalmo.microsoft.com" 
                                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                                SchemaVersion="" PlatformVersion=""" + '\"' +
            malmo_version + '\"' + """>
                                <ExperimentUID></ExperimentUID>
                                <ClientRole>0</ClientRole>
                                <ClientAgentConnection>
                                    <ClientIPAddress>127.0.0.1</ClientIPAddress>
                                    <ClientMissionControlPort>0</ClientMissionControlPort>
                                    <ClientCommandsPort>0</ClientCommandsPort>
                                    <AgentIPAddress>127.0.0.1</AgentIPAddress>
                                    <AgentMissionControlPort>0</AgentMissionControlPort>
                                    <AgentVideoPort>0</AgentVideoPort>
                                    <AgentDepthPort>0</AgentDepthPort>
                                    <AgentLuminancePort>0</AgentLuminancePort>
                                    <AgentObservationsPort>0</AgentObservationsPort>
                                    <AgentRewardsPort>0</AgentRewardsPort>
                                    <AgentColourMapPort>0</AgentColourMapPort>
                                    </ClientAgentConnection>
                                </MissionInit>""")
        e.insert(0, self.xml)
        self.xml = e
        self.xml.find(self.ns + 'ClientRole').text = str(self.role)
        self.xml.find(self.ns + 'ExperimentUID').text = self.exp_uid
        if self.role != 0 and self.agent_count > 1:
            e = etree.Element(self.ns + 'MinecraftServerConnection',
                              attrib={
                                  'address': self.instance.host,
                                  'port': str(0)
                              })
            self.xml.insert(2, e)

        video_producers = self.xml.findall('.//' + self.ns + 'VideoProducer')
        assert len(video_producers) == self.agent_count
        video_producer = video_producers[self.role]
        # Todo: Deprecate width, height, and POV forcing.
        self.width = int(video_producer.find(self.ns + 'Width').text)
        self.height = int(video_producer.find(self.ns + 'Height').text)
        want_depth = video_producer.attrib["want_depth"]
        self.depth = 4 if want_depth is not None and (
            want_depth == "true" or want_depth == "1"
            or want_depth is True) else 3
        # print(etree.tostring(self.xml))

        self.has_init = True