Exemple #1
0
    def _connect(self, timeout: float, request_control: bool) -> None:
        """The function that runs on the connection thread. This will connect to Vector,
        and establish the BehaviorControl stream.
        """
        try:
            if threading.main_thread() is threading.current_thread():
                raise Exception("\n\nConnection._connect must be run outside of the main thread.")
            self._loop = asyncio.new_event_loop()
            asyncio.set_event_loop(self._loop)
            self._done_signal = asyncio.Event()
            self._control_events = _ControlEventManager(self._loop)
            trusted_certs = None
            with open(self.cert_file, 'rb') as cert:
                trusted_certs = cert.read()

            # Pin the robot certificate for opening the channel
            channel_credentials = aiogrpc.ssl_channel_credentials(root_certificates=trusted_certs)
            # Add authorization header for all the calls
            call_credentials = aiogrpc.access_token_call_credentials(self._guid)

            credentials = aiogrpc.composite_channel_credentials(channel_credentials, call_credentials)

            self._logger.info(f"Connecting to {self.host} for {self.name} using {self.cert_file}")
            self._channel = aiogrpc.secure_channel(self.host, credentials,
                                                   options=(("grpc.ssl_target_name_override", self.name,),))

            # Verify the connection to Vector is able to be established (client-side)
            try:
                # Explicitly grab _channel._channel to test the underlying grpc channel directly
                grpc.channel_ready_future(self._channel._channel).result(timeout=timeout)  # pylint: disable=protected-access
            except grpc.FutureTimeoutError as e:
                raise exceptions.VectorNotFoundException() from e

            self._interface = client.ExternalInterfaceStub(self._channel)

            # Verify Vector and the SDK have compatible protocol versions
            version = protocol.ProtocolVersionRequest(client_version=0, min_host_version=0)
            protocol_version = self._loop.run_until_complete(self._interface.ProtocolVersion(version))
            if protocol_version.result != protocol.ProtocolVersionResponse.SUCCESS:  # pylint: disable=no-member
                raise exceptions.VectorInvalidVersionException(version, protocol_version)

            self._control_stream_task = self._loop.create_task(self._open_connections())
            # WV -->--
            if (request_control): self._loop.run_until_complete(self._request_control(timeout=timeout))
            # WV --<--
        except Exception as e:  # pylint: disable=broad-except
            # Propagate the errors to the calling thread
            setattr(self._ready_signal, "exception", e)
            return
        finally:
            self._ready_signal.set()

        async def wait_until_done():
            return await self._done_signal.wait()
        self._loop.run_until_complete(wait_until_done())
Exemple #2
0
    def _connect(self, timeout: float) -> None:
        """The function that runs on the connection thread. This will connect to Vector,
        and establish the BehaviorControl stream.
        """
        try:
            if threading.main_thread() is threading.current_thread():
                raise Exception(
                    "\n\nConnection._connect must be run outside of the main thread."
                )
            self._loop = asyncio.new_event_loop()
            asyncio.set_event_loop(self._loop)
            self._done_signal = asyncio.Event()
            if not self._requires_behavior_control:
                self._control_events = _ControlEventManager(self._loop)
            else:
                self._control_events = _ControlEventManager(
                    self._loop,
                    priority=CONTROL_PRIORITY_LEVEL.TOP_PRIORITY_AI)
            trusted_certs = None
            with open(self.cert_file, 'rb') as cert:
                trusted_certs = cert.read()

            # Pin the robot certificate for opening the channel
            channel_credentials = aiogrpc.ssl_channel_credentials(
                root_certificates=trusted_certs)
            # Add authorization header for all the calls
            call_credentials = aiogrpc.access_token_call_credentials(
                self._guid)

            credentials = aiogrpc.composite_channel_credentials(
                channel_credentials, call_credentials)

            self._logger.info(
                f"Connecting to {self.host} for {self.name} using {self.cert_file}"
            )
            self._channel = aiogrpc.secure_channel(
                self.host,
                credentials,
                options=((
                    "grpc.ssl_target_name_override",
                    self.name,
                ), ))

            # Verify the connection to Vector is able to be established (client-side)
            try:
                # Explicitly grab _channel._channel to test the underlying grpc channel directly
                grpc.channel_ready_future(self._channel._channel).result(
                    timeout=timeout)  # pylint: disable=protected-access
            except grpc.FutureTimeoutError as e:
                raise VectorNotFoundException() from e

            self._interface = client.ExternalInterfaceStub(self._channel)

            # Verify Vector and the SDK have compatible protocol versions
            version = protocol.ProtocolVersionRequest(
                client_version=CLIENT_VERSION,
                min_host_version=MIN_HOST_VERSION)
            protocol_version = self._loop.run_until_complete(
                self._interface.ProtocolVersion(version))
            if protocol_version.result != protocol.ProtocolVersionResponse.SUCCESS or MIN_HOST_VERSION > protocol_version.host_version:  # pylint: disable=no-member
                raise VectorInvalidVersionException(version, protocol_version)

            self._control_stream_task = self._loop.create_task(
                self._open_connections())

            # Initialze SDK
            sdk_module_version = __version__
            python_version = platform.python_version()
            python_implementation = platform.python_implementation()
            os_version = platform.platform()
            cpu_version = platform.machine()
            initialize = protocol.SDKInitializationRequest(
                sdk_module_version=sdk_module_version,
                python_version=python_version,
                python_implementation=python_implementation,
                os_version=os_version,
                cpu_version=cpu_version)
            self._loop.run_until_complete(
                self._interface.SDKInitialization(initialize))

            if self._requires_behavior_control:
                self._loop.run_until_complete(
                    self._request_control(timeout=timeout))
        except Exception as e:  # pylint: disable=broad-except
            # Propagate the errors to the calling thread
            setattr(self._ready_signal, "exception", e)
            self._loop.close()
            return
        finally:
            self._ready_signal.set()

        try:

            async def wait_until_done():
                return await self._done_signal.wait()

            self._loop.run_until_complete(wait_until_done())
        finally:
            self._loop.close()