{"id":6251,"date":"2022-09-15T15:32:54","date_gmt":"2022-09-15T15:32:54","guid":{"rendered":"https:\/\/robotica-facil-con-ros2.es\/?p=6251"},"modified":"2024-12-01T18:57:26","modified_gmt":"2024-12-01T18:57:26","slug":"ros2-servicios","status":"publish","type":"post","link":"https:\/\/robotica-facil-con-ros2.es\/?p=6251","title":{"rendered":"ROS2. Aprende c\u00f3mo usar servicios con Python"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"6251\" class=\"elementor elementor-6251\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-3c6b921 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"3c6b921\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-a1e7b85\" data-id=\"a1e7b85\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-3e2ad92 elementor-widget elementor-widget-text-editor\" data-id=\"3e2ad92\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3>1 Introducci\u00f3n<\/h3><p>Adem\u00e1s de mediante topics, otra forma de hacer que los nodos se comuniquen entre s\u00ed es mediante el uso de servicios. Los servicios est\u00e1n basados en el modelo <em><strong>cliente-servidor<\/strong><\/em> seg\u00fan el cual un nodo (<em>cliente<\/em>) env\u00eda una petici\u00f3n a otro nodo (<em>servidor<\/em>) que responde proporcionado el resultado de la solicitud.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b0e0481 elementor-widget elementor-widget-text-editor\" data-id=\"b0e0481\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>La comunicaci\u00f3n entre el cliente y el servidor puede realizarse de formas:<\/p><p>\u00a0<\/p><ul><li style=\"list-style-type: none;\"><ul><li style=\"list-style-type: none;\"><ul><li><strong>S\u00edncrona.<\/strong> El cliente, tras enviar la petici\u00f3n, detiene su ejecuci\u00f3n hasta recibir la respuesta.<\/li><li><strong>As\u00edncrona.<\/strong> El cliente no detiene su ejecuci\u00f3n cuando env\u00eda la petici\u00f3n al servidor.<\/li><\/ul><\/li><\/ul><\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a9c4b59 elementor-widget elementor-widget-text-editor\" data-id=\"a9c4b59\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tTanto la solicitud como la respuesta est\u00e1n definidas en un archivo con extensi\u00f3n <code class=\"docutils literal notranslate\"><span class=\"pre\" style=\"padding-left: 5px; padding-right: 5px; background-color: #f5f5f5; color: blue; border: 1px solid blue;\">.srv<\/span><\/code> que tiene una estructura como la siguiente:\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-04f829c elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"04f829c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-04f829c\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-tomorrow\"\n            data-dark-theme=\"mdp-theme-tomorrow\"\n        >\n            \n                <pre class=\"language-shell-session copy-to-clipboard\"data-previewers=\"\"><code>int64 a\nint64 b\n---\nint64 sum<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_04f829c = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_04f829c();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_04f829c );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3e60d82 elementor-widget elementor-widget-text-editor\" data-id=\"3e60d82\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Donde cada l\u00ednea indica un dato que se deben pasar o que devuelve el servicio. Siendo los que se encuentran antes de\u00a0 \u00ab<strong>&#8211;\u00a0 &#8211;\u00a0 &#8211;<\/strong>\u00bb\u00a0 los correspondientes a la petici\u00f3n y los que se encuentran despu\u00e9s los asociados a la respuesta. Para cada uno de los datos se indica su tipo y el nombre.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-cedbd18 elementor-widget elementor-widget-text-editor\" data-id=\"cedbd18\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>La estructura mostrada forma parte de un servicio definido en el paquete <em>example_interfaces<\/em> con el nombre <em>AddTwoInts<\/em>, el cual recibe dos valores enteros (<em>a<\/em> y <em>b<\/em>) y devuelve el resultado de su suma (<em>sum<\/em>).<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8263239 elementor-widget elementor-widget-text-editor\" data-id=\"8263239\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>En este art\u00edculo vamos a generar un nuevo paquete python que llamaremos <strong><i>py_srvcli<\/i><\/strong> en el cual crearemos un nodo servidor que va a implementar este servicio y un nodo cliente que realizar\u00e1 las peticiones.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4b8a46c elementor-widget elementor-widget-text-editor\" data-id=\"4b8a46c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3>2 Generando el paquete python<\/h3><p>Para crear el paquete vamos a la carpeta <i>src<\/i> de nuestro espacio de trabajo y ejecutamos el siguiente comando:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-dd149a2 elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"dd149a2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-dd149a2\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-tomorrow\"\n            data-dark-theme=\"mdp-theme-tomorrow\"\n        >\n            \n                <pre class=\"language-shell-session copy-to-clipboard\"data-previewers=\"\"><code>ros2 pkg create --build-type ament_python py_srvcli --dependencies rclpy example_interfaces<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_dd149a2 = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_dd149a2();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_dd149a2 );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c184944 elementor-widget elementor-widget-text-editor\" data-id=\"c184944\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>C\u00f3mo en el comando anterior ya hemos indicado las dependencias estas ya se incluyen autom\u00e1ticamente en el archivo <em>package.xml<\/em> del paquete por lo que no es necesario editarlo para a\u00f1adirlas manualmente.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5655040 elementor-widget elementor-widget-text-editor\" data-id=\"5655040\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Si quieres conocer los argumentos que se pueden usar a la hora de generar un paquete puedes consultar el art\u00edculo <a href=\"https:\/\/robotica-facil-con-ros2.es\/?p=3078\">\u00abROS2. C\u00f3mo crear un paquete Python\u00bb<\/a>.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d540b2a elementor-widget elementor-widget-text-editor\" data-id=\"d540b2a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3>3 Creando el nodo servidor que proporciona el servicio<\/h3><p>Para ello, en nuestro paquete dentro de la carpeta que tiene su mismo nombre, creamos un archivo al que vamos a llamar <strong><em>server_node.py<\/em><\/strong>:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c47445c elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"c47445c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-c47445c\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-tomorrow\"\n            data-dark-theme=\"mdp-theme-tomorrow\"\n        >\n            \n                <pre class=\"language-shell-session copy-to-clipboard\"data-previewers=\"\"><code>cd py_srvcli\/py_srvcli\ntouch server_node.py<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_c47445c = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_c47445c();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_c47445c );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ee827b6 elementor-widget elementor-widget-text-editor\" data-id=\"ee827b6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Abrimos el archivo y pegamos una de las dos versiones de c\u00f3digo que se muestran a continuaci\u00f3n. La diferencia entre ellas es que en una se ha utilizado programaci\u00f3n orientada a objetos y en la otra no.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ffce0a5 elementor-widget elementor-widget-text-editor\" data-id=\"ffce0a5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>El c\u00f3digo se encuentra explicado en los comentarios.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c4ea73c elementor-widget elementor-widget-text-editor\" data-id=\"c4ea73c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h4>3.1 Usando una funci\u00f3n local<\/h4>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c271768 elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"c271768\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-c271768\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-xonokai\"\n            data-dark-theme=\"mdp-theme-xonokai\"\n        >\n            \n                <pre class=\"language-python copy-to-clipboard\"data-previewers=\"\"><code># Importa el tipo de servicio AddTwoInts del paquete example_interface. \nfrom example_interfaces.srv import AddTwoInts\n\n# Importa la biblioteca cliente Python de ROS 2.\nimport rclpy\n\n# Crea una variable global que se usar&aacute; m&aacute;s adelante para almacenar la \n# instancia del nodo.\nnode = None\n\n# Define la funci&oacute;n que se ejecuta al recibir una petici&oacute;n y que devuelve\n# la respuesta del servicio.\ndef add_two_ints_callback(request, response):\n    global node\n\n    # Asigna el resultado a la respuesta del servicio.\n    response.sum = request.a + request.b\n\n    # Muestra en la consola la informaci&oacute;n de la petici&oacute;n recibida.\n    node.get_logger().info(\n        &#039;Incoming request\\na: %d b: %d&#039; % (request.a, request.b))\n\n    # Devuelve la respuesta del servicio.\n    return response\n\n\ndef main(args=None):\n    global node\n\n    # Inicializa la librer&iacute;a Python de ROS2.\n    rclpy.init(args=args)\n\n    # Crea el nodo que va a proporcionar el servicio.\n    node = rclpy.create_node(&#039;minimal_service&#039;)\n\n    # Crea el servicio y define el tipo, su nombre y el de la funci&oacute;n que se\n    # ejecutara al recibir una petici&oacute;n.\n    srv = node.create_service(AddTwoInts, &#039;add_two_ints&#039;, add_two_ints_callback)\n\n    # Mantiene corriendo el bucle interno del nodo para poder gestionar las\n    # peticiones del cliente.\n    rclpy.spin(node)\n\n    # Destruye expl&iacute;citamente el servicio. Es opcional ya que el recolector de\n    # basura realiza esta acci&oacute;n cuandop destruye el objeto nodo.\n    node.destroy_service(srv)\n\n    # Destruye el nodo.\n    node.destroy_node()\n\n    rclpy.shutdown()\n\n\nif __name__ == &#039;__main__&#039;:\n    main()<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_c271768 = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_c271768();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_c271768 );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-88b9d73 elementor-widget elementor-widget-text-editor\" data-id=\"88b9d73\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h4>3.2 Usando una clase<\/h4>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-51b9921 elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"51b9921\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-51b9921\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-xonokai\"\n            data-dark-theme=\"mdp-theme-xonokai\"\n        >\n            \n                <pre class=\"language-python copy-to-clipboard\"data-previewers=\"\"><code># Importa el tipo de servicio AddTwoInts del paquete example_interface. \nfrom example_interfaces.srv import AddTwoInts\n\n# Importa la biblioteca cliente Python de ROS 2 y, espec&iacute;ficamente, la clase Node.\nimport rclpy\nfrom rclpy.node import Node\n\n\nclass MinimalService(Node):\n\n    # El constructor de la clase inicializa el nodo con el nombre service_node.\n    # Luego, crea un servicio y define el tipo, su nombre y el de la funci&oacute;n que\n    # se ejecutar&aacute; al recibir una petici&oacute;n.\n    def __init__(self):\n        super().__init__(&#039;service_node&#039;)\n        self.srv = self.create_service(AddTwoInts, &#039;add_two_ints&#039;, self.add_two_ints_callback)\n\n    # Define la funci&oacute;n que se ejecuta al recibir una petici&oacute;n y que devuelve\n    # la respuesta del servicio.\n    def add_two_ints_callback(self, request, response):\n        response.sum = request.a + request.b\n        self.get_logger().info(&#039;Incoming request\\na: %d b: %d&#039; % (request.a, request.b))\n\n        return response\n\n\ndef main(args=None):\n\n    # Inicializa la librer&iacute;a Python de ROS2.\n    rclpy.init(args=args)\n\n    # Crea una instancia de la clase.\n    node = MinimalService()\n\n    # Mantiene corriendo el bucle interno del nodo para poder gestionar las\n    # peticiones del cliente.\n    rclpy.spin(node)\n\n    rclpy.shutdown()\n\n\nif __name__ == &#039;__main__&#039;:\n    main()<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_51b9921 = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_51b9921();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_51b9921 );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-951eae4 elementor-widget elementor-widget-text-editor\" data-id=\"951eae4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3>4 Creando el nodo cliente<\/h3><p>Creamos mediante el siguiente comando, en la misma ubicaci\u00f3n,\u00a0 el archivo <em><strong>client_node.py<\/strong><\/em> que va a contener el c\u00f3digo de nuestro nodo cliente.\u00a0<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-bd9cb33 elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"bd9cb33\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-bd9cb33\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-tomorrow\"\n            data-dark-theme=\"mdp-theme-tomorrow\"\n        >\n            \n                <pre class=\"language-shell-session copy-to-clipboard\"data-previewers=\"\"><code>touch client_node.py<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_bd9cb33 = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_bd9cb33();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_bd9cb33 );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-296d050 elementor-widget elementor-widget-text-editor\" data-id=\"296d050\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Abrimos el archivo y al igual que hemos hecho con el nodo servidor pegamos una de las versiones de c\u00f3digo que se muestran a continuaci\u00f3n, en funci\u00f3n de que queramos realizar la petici\u00f3n al servicio de forma <strong>s\u00edncrona<\/strong> o <strong>as\u00edncrona<\/strong> y de que queramos usar una clase o no.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-144dc3e elementor-widget elementor-widget-text-editor\" data-id=\"144dc3e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>El c\u00f3digo se encuentra explicado en los comentarios.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-370fa96 elementor-widget elementor-widget-text-editor\" data-id=\"370fa96\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h4>4.1 Cliente con comunicaci\u00f3n s\u00edncrona<\/h4><p>En este caso el cliente realiza la petici\u00f3n al servicio y <u>su ejecuci\u00f3n se detiene<\/u> hasta recibir la respuesta.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e7188e1 elementor-widget elementor-widget-text-editor\" data-id=\"e7188e1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Hay que destacar que, aunque el objetivo de este apartado es ver un ejemplo de cliente con comunicaci\u00f3n s\u00edncrona con el servidor, las dos versiones de c\u00f3digo que se muestran a continuaci\u00f3n realmente realizan una llamada as\u00edncrona al servicio mediante <code class=\"docutils literal notranslate\"><span class=\"pre\" style=\"padding-left: 5px; padding-right: 5px; background-color: #f5f5f5; color: blue; border: 1px solid blue;\">.call_async()<\/span><\/code> y luego esperan a recibir la respuesta mediante <code class=\"docutils literal notranslate\"><span class=\"pre\" style=\"padding-left: 5px; padding-right: 5px; background-color: #f5f5f5; color: blue; border: 1px solid blue;\">.spin_until_future_complete()<\/span><\/code>.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c61410e elementor-widget elementor-widget-text-editor\" data-id=\"c61410e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Aunque rclpy tiene la funci\u00f3n <code class=\"docutils literal notranslate\"><span class=\"pre\" style=\"padding-left: 5px; padding-right: 5px; background-color: #f5f5f5; color: blue; border: 1px solid blue;\">.call()<\/span><\/code> para realizar una verdadera llamada s\u00edncrona al servicio su uso puede causar interbloqueos, por ejemplo con <code class=\"docutils literal notranslate\"><span class=\"pre\" style=\"padding-left: 5px; padding-right: 5px; background-color: #f5f5f5; color: blue; border: 1px solid blue;\">rclpy.spin()<\/span><\/code> si este \u00faltimo no se lanza en un hilo diferente. Es por ello que se recomienda el uso de <code class=\"docutils literal notranslate\"><span class=\"pre\" style=\"padding-left: 5px; padding-right: 5px; background-color: #f5f5f5; color: blue; border: 1px solid blue;\">.call_async()<\/span><\/code>, que es totalmente seguro.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ff8db4e elementor-widget elementor-widget-text-editor\" data-id=\"ff8db4e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Si de todas formas estas interesado en ver c\u00f3mo usar <code class=\"docutils literal notranslate\"><span class=\"pre\" style=\"padding-left: 5px; padding-right: 5px; background-color: #f5f5f5; color: blue; border: 1px solid blue;\">.call()<\/span><\/code> sin provocar interbloqueos puedes echarle un ojo a <a href=\"https:\/\/docs.ros.org\/en\/humble\/How-To-Guides\/Sync-Vs-Async.html\">Synchronous vs. asynchronous service clients<\/a> en la documentaci\u00f3n de ROS2 Humble Hawksbill.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-529dbfa elementor-widget elementor-widget-text-editor\" data-id=\"529dbfa\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h5>4.1.1 Sin usar clases<\/h5>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-dcc22e8 elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"dcc22e8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-dcc22e8\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-xonokai\"\n            data-dark-theme=\"mdp-theme-xonokai\"\n        >\n            \n                <pre class=\"language-python copy-to-clipboard\"data-previewers=\"\"><code># Importa el tipo de servicio AddTwoInts del paquete example_interface. \nfrom example_interfaces.srv import AddTwoInts\n\n# Importa la libreria Python de ROS 2.\nimport rclpy\n\n\ndef main(args=None):\n\n    # Inicializa la librer&iacute;a Python de ROS2.\n    rclpy.init(args=args)\n\n    # Crea el nodo.\n    node = rclpy.create_node(&#039;minimal_client&#039;)\n\n    # Crea un cliente y define el tipo, su nombre.\n    cli = node.create_client(AddTwoInts, &#039;add_two_ints&#039;)\n\n    # Crea una variable de tipo petici&oacute;n y almacena en ella la informaci&oacute;n\n    # que se proporcionar&aacute; al servicio.\n    req = AddTwoInts.Request()\n    req.a = 41\n    req.b = 1\n\n    # Espera a que el servicio est&eacute; disponible.\n    while not cli.wait_for_service(timeout_sec=1.0):\n        node.get_logger().info(&#039;service not available, waiting again...&#039;)\n\n    # Env&iacute;a la petici&oacute;n al servicio.\n    future = cli.call_async(req)\n\n    # Espera hasta que el servicio haya proporcionado la respuesta.\n    rclpy.spin_until_future_complete(node, future)\n\n    # Obtiene la informaci&oacute;n de la respuesta.\n    result = future.result()\n\n    # Muestra en la consola los valores suministrados al servicio\n    # y el resultado recibido como respuesta.\n    node.get_logger().info(\n        &#039;Result of add_two_ints: for %d + %d = %d&#039; %\n        (req.a, req.b, result.sum))\n\n    # Destruye expl&iacute;citamente el servicio. Es opcional ya que el recolector de\n    # basura realiza esta acci&oacute;n cuandop destruye el objeto nodo.\n    node.destroy_service(srv)\n\n    # Destruye el nodo.\n    node.destroy_node()\n\n    rclpy.shutdown()\n\n\nif __name__ == &#039;__main__&#039;:\n    main()<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_dcc22e8 = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_dcc22e8();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_dcc22e8 );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-33cd4ce elementor-widget elementor-widget-text-editor\" data-id=\"33cd4ce\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h5>4.1.1 Usando una clase<\/h5>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7527e79 elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"7527e79\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-7527e79\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-xonokai\"\n            data-dark-theme=\"mdp-theme-xonokai\"\n        >\n            \n                <pre class=\"language-python copy-to-clipboard\"data-previewers=\"\"><code># Importa el tipo de servicio AddTwoInts del paquete example_interface. \nfrom example_interfaces.srv import AddTwoInts\n\n# Importa la libreria Python de ROS 2 y, espec&iacute;ficamente, la clase node.\nimport rclpy\nfrom rclpy.node import Node\n\n# Definimos la clase que va a crear el nodo y contiene la funci&oacute;n que realizar&aacute;\n# la petici&oacute;n al servicio.\nclass MinimalClient(Node):\n\n    # El constructor de la clase inicializa el nodo con el nombre minimal_client_async.\n    # Luego, crea un servicio y define el tipo, su nombre y el de la funci&oacute;n que\n    # se ejecutar&aacute; al recibir una petici&oacute;n. Y finalmente espera a que el servicio\n    # est&eacute; disponible.\n    def __init__(self):\n        # El constructor de la clase inicializa el nodo y le asigna el nombre \n        # minimal_client_async.\n        super().__init__(&#039;minimal_client_async&#039;)\n\n        # Crea un servicio y define el tipo, su nombre y el de la funci&oacute;n que\n        # se ejecutar&aacute; al recibir una petici&oacute;n.\n        self.cli = self.create_client(AddTwoInts, &#039;add_two_ints&#039;)\n\n        # Espera a que el servicio est&eacute; disponible.\n        while not self.cli.wait_for_service(timeout_sec=1.0):\n            self.get_logger().info(&#039;service not available, waiting again...&#039;)\n\n        # Crea la variable que almacenar&aacute; los datos que se enviar&aacute;n en la petici&oacute;n\n        # al servicio.\n        self.req = AddTwoInts.Request()\n\n    # Define la funci&oacute;n que realiza la petici&oacute;n al servicio.\n    def send_request(self):\n        self.req.a = 41\n        self.req.b = 1\n        self.future = self.cli.call_async(self.req)\n\n\ndef main(args=None):\n\n    # Inicializa la librer&iacute;a Python de ROS2.\n    rclpy.init(args=args)\n\n    # Crea el nodo.\n    node = MinimalClient()\n\n    # Realiza la petici&oacute;n al servicio.\n    node.send_request()\n\n    # Espera hasta que el servicio haya proporcionado la respuesta.\n    rclpy.spin_until_future_complete(node, node.future)\n\n    # Lee la informaci&oacute;n de la respuesta.\n    result = node.future.result()\n\n    # Muestra la informaci&oacute;n en la consola.\n    node.get_logger().info(\n        &#039;Result of add_two_ints: for %d + %d = %d&#039; %\n        (node.req.a, node.req.b, result.sum))\n\n\n    # Destruye el nodo.\n    node.destroy_node()\n    \n    rclpy.shutdown()\n\n\nif __name__ == &#039;__main__&#039;:\n    main()<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_7527e79 = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_7527e79();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_7527e79 );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8ad4db2 elementor-widget elementor-widget-text-editor\" data-id=\"8ad4db2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h4>4.2 Cliente con comunicaci\u00f3n as\u00edncrona<\/h4>\nEn este caso el cliente realiza la petici\u00f3n al servicio pero <span style=\"text-decoration: underline;\">no detiene su ejecuci\u00f3n<\/span>, por lo que es necesario en el c\u00f3digo crear un bucle y comprobar que se ha recibido la respuesta usando <code class=\"docutils literal notranslate\"><span class=\"pre\" style=\"padding-left: 5px; padding-right: 5px; background-color: #f5f5f5; color: blue; border: 1px solid blue;\">.done()<\/span><\/code> antes de acceder al resultado con <code class=\"docutils literal notranslate\"><span class=\"pre\" style=\"padding-left: 5px; padding-right: 5px; background-color: #f5f5f5; color: blue; border: 1px solid blue;\">.result()<\/span><\/code>.\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-489da88 elementor-widget elementor-widget-text-editor\" data-id=\"489da88\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h5>4.2.1 Sin usar clases<\/h5>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-79875af elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"79875af\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-79875af\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-xonokai\"\n            data-dark-theme=\"mdp-theme-xonokai\"\n        >\n            \n                <pre class=\"language-python copy-to-clipboard\"data-previewers=\"\"><code># Importa el tipo de servicio AddTwoInts del paquete example_interface. \nfrom example_interfaces.srv import AddTwoInts\n\n# Importa la libreria Python de ROS 2.\nimport rclpy\n\n\ndef main(args=None):\n\n    # Inicializa la librer&iacute;a Python de ROS2.\n    rclpy.init(args=args)\n\n    # Crea el nodo.\n    node = rclpy.create_node(&#039;minimal_client_async&#039;)\n\n    # Crea un cliente y define el tipo, su nombre.\n    cli = node.create_client(AddTwoInts, &#039;add_two_ints&#039;)\n\n    # Crea una variable de tipo petici&oacute;n y almacena en ella la informaci&oacute;n\n    # que se proporcionar&aacute; al servicio.\n    req = AddTwoInts.Request()\n    req.a = 41\n    req.b = 1\n\n    # Espera a que el servicio est&eacute; disponible.\n    while not cli.wait_for_service(timeout_sec=1.0):\n        node.get_logger().info(&#039;service not available, waiting again...&#039;)\n\n    # Env&iacute;a la petici&oacute;n al servicio.\n    future = cli.call_async(req)\n\n    # Bucle infinito hasta que se reciba la respuesta del servicio.\n    while rclpy.ok():\n\n        # Ejecuta una sola vez el bucle interno del nodo, actualizando los \n        # buffers de entrada (llegada de topics, respuestas de servicios...).  \n        rclpy.spin_once(node)\n\n        # Comprueba si el servicio ha proporcionado la respuesta.\n        if future.done():\n\n            # Lee la informaci&oacute;n de la respuesta.\n            result = future.result()\n\n            # Muestra la informaci&oacute;n en la consola.\n            node.get_logger().info(\n                &#039;Result of add_two_ints: for %d + %d = %d&#039; %\n                (req.a, req.b, result.sum))\n\n            # Interrumpe el bucle.\n            break\n\n\n    # Destruye expl&iacute;citamente el servicio. Es opcional ya que el recolector de\n    # basura realiza esta acci&oacute;n cuandop destruye el objeto nodo.\n    node.destroy_service(srv)\n\n    # Destruye el nodo.\n    node.destroy_node()\n\n    rclpy.shutdown()\n\n\nif __name__ == &#039;__main__&#039;:\n    main()<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_79875af = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_79875af();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_79875af );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8c8db81 elementor-widget elementor-widget-text-editor\" data-id=\"8c8db81\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h5>4.2.2 Usando una clase<\/h5>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f0d1ecb elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"f0d1ecb\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-f0d1ecb\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-xonokai\"\n            data-dark-theme=\"mdp-theme-xonokai\"\n        >\n            \n                <pre class=\"language-python copy-to-clipboard\"data-previewers=\"\"><code># Importa el tipo de servicio AddTwoInts del paquete example_interface. \nfrom example_interfaces.srv import AddTwoInts\n\n# Importa la libreria Python de ROS 2 y, espec&iacute;ficamente, la clase node.\nimport rclpy\nfrom rclpy.node import Node\n\n# Definimos la clase que va a crear el nodo y contiene la funci&oacute;n que realizar&aacute;\n# la petici&oacute;n al servicio.\nclass MinimalClientAsync(Node):\n\n    # El constructor de la clase inicializa el nodo con el nombre minimal_client_async.\n    # Luego, crea un servicio y define el tipo, su nombre y el de la funci&oacute;n que\n    # se ejecutar&aacute; al recibir una petici&oacute;n. Y finalmente espera a que el servicio\n    # est&eacute; disponible.\n    def __init__(self):\n        # El constructor de la clase inicializa el nodo y le asigna el nombre \n        # minimal_client_async.\n        super().__init__(&#039;minimal_client_async&#039;)\n\n        # Crea un servicio y define el tipo, su nombre y el de la funci&oacute;n que\n        # se ejecutar&aacute; al recibir una petici&oacute;n.\n        self.cli = self.create_client(AddTwoInts, &#039;add_two_ints&#039;)\n\n        # Espera a que el servicio est&eacute; disponible.\n        while not self.cli.wait_for_service(timeout_sec=1.0):\n            self.get_logger().info(&#039;service not available, waiting again...&#039;)\n\n        # Crea la variable que almacenar&aacute; los datos que se enviar&aacute;n en la petici&oacute;n\n        # al servicio.\n        self.req = AddTwoInts.Request()\n\n    # Define la funci&oacute;n que realiza la petici&oacute;n al servicio.\n    def send_request(self):\n        self.req.a = 41\n        self.req.b = 1\n        self.future = self.cli.call_async(self.req)\n\n\ndef main(args=None):\n\n    # Inicializa la librer&iacute;a Python de ROS2.\n    rclpy.init(args=args)\n\n    # Crea el nodo.\n    node = MinimalClientAsync()\n\n    # Realiza la petici&oacute;n al servicio.\n    node.send_request()\n\n    # Bucle infinito hasta que se reciba la respuesta del servicio.\n    while rclpy.ok():\n\n        # Ejecuta una sola vez el bucle interno del nodo, actualizando los \n        # buffers de entrada (llegada de topics, respuestas de servicios...). \n        rclpy.spin_once(node)\n\n        # Comprueba si el servicio ha proporcionado la respuesta.\n        if node.future.done():\n\n            # Lee la informaci&oacute;n de la respuesta.\n            result = node.future.result()\n\n            # Muestra la informaci&oacute;n en la consola.\n            node.get_logger().info(\n                &#039;Result of add_two_ints: for %d + %d = %d&#039; %\n                (node.req.a, node.req.b, result.sum))\n\n            # Interrumpe el bucle.\n            break\n\n    # Destruye el nodo.\n    node.destroy_node()\n    \n    rclpy.shutdown()\n\n\nif __name__ == &#039;__main__&#039;:\n    main()<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_f0d1ecb = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_f0d1ecb();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_f0d1ecb );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9b4542f elementor-widget elementor-widget-text-editor\" data-id=\"9b4542f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3>5 Incorporando los puntos de entrada en setup.py<\/h3><p>El \u00faltimo paso es editar el archivo setup.py para a\u00f1adir al array <strong><em>entry_points<\/em><\/strong> los puntos de entrada para de los scripts de los nodos servidor y cliente, de modo que puedan ejecutarse mediante <em>ros2 run<\/em>.\u00a0<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fa5a6f2 elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"fa5a6f2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-fa5a6f2\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-xonokai\"\n            data-dark-theme=\"mdp-theme-xonokai\"\n        >\n            \n                <pre class=\"language-python copy-to-clipboard\"data-previewers=\"\"><code>from setuptools import setup\n\npackage_name = &#039;py_srvcli&#039;\n\nsetup(\n    name=package_name,\n    version=&#039;0.0.0&#039;,\n    packages=[package_name],\n    data_files=[\n        (&#039;share\/ament_index\/resource_index\/packages&#039;,\n            [&#039;resource\/&#039; + package_name]),\n        (&#039;share\/&#039; + package_name, [&#039;package.xml&#039;]),\n    ],\n    install_requires=[&#039;setuptools&#039;],\n    zip_safe=True,\n    maintainer=&#039;ros&#039;,\n    maintainer_email=&#039;TODO@gmail.com&#039;,\n    description=&#039;TODO: Package description&#039;,\n    license=&#039;TODO: License declaration&#039;,\n    tests_require=[&#039;pytest&#039;],\n    entry_points={\n        &#039;console_scripts&#039;: [\n              &#039;server = py_srvcli.server_node:main&#039;,\n              &#039;client = py_srvcli.client_node:main&#039;,\n        ],\n    },\n)<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_fa5a6f2 = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_fa5a6f2();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_fa5a6f2 );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e2d4cc7 elementor-widget elementor-widget-text-editor\" data-id=\"e2d4cc7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3>6 Ejecutando los nodos<\/h3><p>Una vez que ya tenemos preparado nuestro paquete lo compilamos desde el directorio ra\u00edz de nuestro espacio de trabajo:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f684480 elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"f684480\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-f684480\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-tomorrow\"\n            data-dark-theme=\"mdp-theme-tomorrow\"\n        >\n            \n                <pre class=\"language-shell-session copy-to-clipboard\"data-previewers=\"\"><code>colcon build --packages-select py_srvcli\n. install\/setup.bash<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_f684480 = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_f684480();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_f684480 );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-da4a1d4 elementor-widget elementor-widget-text-editor\" data-id=\"da4a1d4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Seguidamente ejecutamos el nodo servidor mediante el siguiente comando:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5b23df4 elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"5b23df4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-5b23df4\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-tomorrow\"\n            data-dark-theme=\"mdp-theme-tomorrow\"\n        >\n            \n                <pre class=\"language-shell-session copy-to-clipboard\"data-previewers=\"\"><code>ros2 run py_srvcli server<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_5b23df4 = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_5b23df4();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_5b23df4 );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-96a2407 elementor-widget elementor-widget-text-editor\" data-id=\"96a2407\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Y finalmente abrimos otro terminal y ejecutamos el nodo cliente:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b7ff3f7 elementor-widget elementor-widget-mdp-coder-elementor\" data-id=\"b7ff3f7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"mdp-coder-elementor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <!-- Start Coder for Elementor WordPress Plugin -->\n        <div\n            id=\"mdp-coder-b7ff3f7\"\n            class=\"mdp-coder-elementor-box\"\n            data-theme=\"mdp-theme-tomorrow\"\n            data-dark-theme=\"mdp-theme-tomorrow\"\n        >\n            \n                <pre class=\"language-shell-session copy-to-clipboard\"data-previewers=\"\"><code>ros2 run py_srvcli client<\/code><\/pre>\n                    <\/div>\n                <script>\n            \"use strict\";\n\n            \/** Handler when the DOM is fully loaded. *\/\n            let callback_b7ff3f7 = function() {\n\n                \/** Set theme for coder widget. *\/\n                function setTheme() {\n\n                    \/** Foreach Code Widget. *\/\n                    let coderBoxes = document.querySelectorAll( '.mdp-coder-elementor-box' );\n\n                    for ( let coderBox of coderBoxes ) {\n\n                        let lightTheme = coderBox.dataset.theme;\n                        let darkTheme = coderBox.dataset.darkTheme;\n\n                        coderBox.className = '';\n                        if ( window.matchMedia && window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + darkTheme;\n\n                        } else {\n\n                            coderBox.className = 'mdp-coder-elementor-box ' + lightTheme;\n\n                        }\n\n                    }\n\n                }\n                setTheme();\n\n\n                \/** Watch for changes color-scheme. *\/\n                window.matchMedia(\"(prefers-color-scheme: dark)\").addListener( function() {\n                    setTheme();\n                } );\n\n                \n                if ( typeof Prism !== 'undefined' ) {\n\n                    Prism.plugins.autoloader.languages_path = 'https:\/\/robotica-facil-con-ros2.es\/wp-content\/plugins\/coder-elementor\/js\/prism\/components\/';\n                    Prism.highlightAll();\n                    Prism.fileHighlight();\n\n                }\n\n                \n            };\n\n            if (\n                document.readyState === \"complete\" ||\n                ( document.readyState !== \"loading\" && !document.documentElement.doScroll )\n            ) {\n                callback_b7ff3f7();\n            } else {\n                document.addEventListener( \"DOMContentLoaded\", callback_b7ff3f7 );\n            }\n\n        <\/script>\n                <!-- End Coder for Elementor WordPress Plugin -->\n\n        \t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-182ad44 elementor-widget elementor-widget-text-editor\" data-id=\"182ad44\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Si hemos seguido los pasos correctamente deber\u00edamos ver en un terminal los datos enviados por el cliente y en el otro la respuesta del servidor.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-76378a0 elementor-widget elementor-widget-image\" data-id=\"76378a0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"786\" height=\"533\" src=\"https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/service-server-output.png\" class=\"attachment-large size-large wp-image-6554\" alt=\"Servicios - Salida por consola del nodo servidor\" srcset=\"https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/service-server-output.png 786w, https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/service-server-output-300x203.png 300w, https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/service-server-output-768x521.png 768w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8722d4d elementor-widget elementor-widget-image\" data-id=\"8722d4d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"759\" height=\"533\" src=\"https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/service-client-output.png\" class=\"attachment-large size-large wp-image-6553\" alt=\"Servicios - Salida por consola del nodo cliente\" srcset=\"https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/service-client-output.png 759w, https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/service-client-output-300x211.png 300w\" sizes=\"(max-width: 759px) 100vw, 759px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>En este art\u00edculo aprender\u00e1s a comunicar dos nodos mediante un servicio usando Python.<\/p>\n","protected":false},"author":1,"featured_media":6611,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"_elementor_version":"3.17.3","footnotes":""},"categories":[5],"tags":[30],"class_list":["post-6251","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ros2","tag-servicios"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.9 - aioseo.com -->\n\t<meta name=\"description\" content=\"En este art\u00edculo aprender\u00e1s a comunicar dos nodos mediante un servicio usando Python.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Jose Enrique Cabrera\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/robotica-facil-con-ros2.es\/?p=6251\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.9\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\n\t\t<meta property=\"og:site_name\" content=\"- ROS2. Aprende c\u00f3mo usar servicios con Python En este art\u00edculo aprender\u00e1s a comunicar dos nodos mediante un servicio usando Python.\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"ROS2. Aprende c\u00f3mo usar servicios con Python -\" \/>\n\t\t<meta property=\"og:description\" content=\"En este art\u00edculo aprender\u00e1s a comunicar dos nodos mediante un servicio usando Python.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/robotica-facil-con-ros2.es\/?p=6251\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png\" \/>\n\t\t<meta property=\"og:image:width\" content=\"840\" \/>\n\t\t<meta property=\"og:image:height\" content=\"426\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2022-09-15T15:32:54+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2024-12-01T18:57:26+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:site\" content=\"@RFconROS2\" \/>\n\t\t<meta name=\"twitter:title\" content=\"ROS2. Aprende c\u00f3mo usar servicios con Python -\" \/>\n\t\t<meta name=\"twitter:description\" content=\"En este art\u00edculo aprender\u00e1s a comunicar dos nodos mediante un servicio usando Python.\" \/>\n\t\t<meta name=\"twitter:creator\" content=\"@RFconROS2\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png\" \/>\n\t\t<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t\t<meta name=\"twitter:data1\" content=\"Jose Enrique Cabrera\" \/>\n\t\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura estimado\" \/>\n\t\t<meta name=\"twitter:data2\" content=\"13 minutos\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251#blogposting\",\"name\":\"ROS2. Aprende c\\u00f3mo usar servicios con Python -\",\"headline\":\"ROS2. Aprende c\\u00f3mo usar servicios con Python\",\"author\":{\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?author=1#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/#person\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/wp-content\\\/uploads\\\/2022\\\/09\\\/Services-1.png\",\"width\":840,\"height\":426,\"caption\":\"Servicios ROS2\"},\"datePublished\":\"2022-09-15T15:32:54+00:00\",\"dateModified\":\"2024-12-01T18:57:26+00:00\",\"inLanguage\":\"es-ES\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251#webpage\"},\"articleSection\":\"ROS2, SERVICIOS\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es#listItem\",\"position\":1,\"name\":\"Inicio\",\"item\":\"https:\\\/\\\/robotica-facil-con-ros2.es\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?cat=5#listItem\",\"name\":\"ROS2\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?cat=5#listItem\",\"position\":2,\"name\":\"ROS2\",\"item\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?cat=5\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251#listItem\",\"name\":\"ROS2. Aprende c\\u00f3mo usar servicios con Python\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es#listItem\",\"name\":\"Inicio\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251#listItem\",\"position\":3,\"name\":\"ROS2. Aprende c\\u00f3mo usar servicios con Python\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?cat=5#listItem\",\"name\":\"ROS2\"}}]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/#person\",\"name\":\"Jose Enrique Cabrera\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251#personImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7fb8a5b8671a5fde1ab097847642f4ec46f3150e6ef27ed7fe4f7055bb02a052?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Jose Enrique Cabrera\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?author=1#author\",\"url\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?author=1\",\"name\":\"Jose Enrique Cabrera\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7fb8a5b8671a5fde1ab097847642f4ec46f3150e6ef27ed7fe4f7055bb02a052?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Jose Enrique Cabrera\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251#webpage\",\"url\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251\",\"name\":\"ROS2. Aprende c\\u00f3mo usar servicios con Python -\",\"description\":\"En este art\\u00edculo aprender\\u00e1s a comunicar dos nodos mediante un servicio usando Python.\",\"inLanguage\":\"es-ES\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?author=1#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?author=1#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/wp-content\\\/uploads\\\/2022\\\/09\\\/Services-1.png\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251\\\/#mainImage\",\"width\":840,\"height\":426,\"caption\":\"Servicios ROS2\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/?p=6251#mainImage\"},\"datePublished\":\"2022-09-15T15:32:54+00:00\",\"dateModified\":\"2024-12-01T18:57:26+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/#website\",\"url\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/\",\"description\":\"Rob\\u00f3tica con ROS2\",\"inLanguage\":\"es-ES\",\"publisher\":{\"@id\":\"https:\\\/\\\/robotica-facil-con-ros2.es\\\/#person\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"ROS2. Aprende c\u00f3mo usar servicios con Python -","description":"En este art\u00edculo aprender\u00e1s a comunicar dos nodos mediante un servicio usando Python.","canonical_url":"https:\/\/robotica-facil-con-ros2.es\/?p=6251","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/robotica-facil-con-ros2.es\/?p=6251#blogposting","name":"ROS2. Aprende c\u00f3mo usar servicios con Python -","headline":"ROS2. Aprende c\u00f3mo usar servicios con Python","author":{"@id":"https:\/\/robotica-facil-con-ros2.es\/?author=1#author"},"publisher":{"@id":"https:\/\/robotica-facil-con-ros2.es\/#person"},"image":{"@type":"ImageObject","url":"https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png","width":840,"height":426,"caption":"Servicios ROS2"},"datePublished":"2022-09-15T15:32:54+00:00","dateModified":"2024-12-01T18:57:26+00:00","inLanguage":"es-ES","mainEntityOfPage":{"@id":"https:\/\/robotica-facil-con-ros2.es\/?p=6251#webpage"},"isPartOf":{"@id":"https:\/\/robotica-facil-con-ros2.es\/?p=6251#webpage"},"articleSection":"ROS2, SERVICIOS"},{"@type":"BreadcrumbList","@id":"https:\/\/robotica-facil-con-ros2.es\/?p=6251#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/robotica-facil-con-ros2.es#listItem","position":1,"name":"Inicio","item":"https:\/\/robotica-facil-con-ros2.es","nextItem":{"@type":"ListItem","@id":"https:\/\/robotica-facil-con-ros2.es\/?cat=5#listItem","name":"ROS2"}},{"@type":"ListItem","@id":"https:\/\/robotica-facil-con-ros2.es\/?cat=5#listItem","position":2,"name":"ROS2","item":"https:\/\/robotica-facil-con-ros2.es\/?cat=5","nextItem":{"@type":"ListItem","@id":"https:\/\/robotica-facil-con-ros2.es\/?p=6251#listItem","name":"ROS2. Aprende c\u00f3mo usar servicios con Python"},"previousItem":{"@type":"ListItem","@id":"https:\/\/robotica-facil-con-ros2.es#listItem","name":"Inicio"}},{"@type":"ListItem","@id":"https:\/\/robotica-facil-con-ros2.es\/?p=6251#listItem","position":3,"name":"ROS2. Aprende c\u00f3mo usar servicios con Python","previousItem":{"@type":"ListItem","@id":"https:\/\/robotica-facil-con-ros2.es\/?cat=5#listItem","name":"ROS2"}}]},{"@type":"Person","@id":"https:\/\/robotica-facil-con-ros2.es\/#person","name":"Jose Enrique Cabrera","image":{"@type":"ImageObject","@id":"https:\/\/robotica-facil-con-ros2.es\/?p=6251#personImage","url":"https:\/\/secure.gravatar.com\/avatar\/7fb8a5b8671a5fde1ab097847642f4ec46f3150e6ef27ed7fe4f7055bb02a052?s=96&d=mm&r=g","width":96,"height":96,"caption":"Jose Enrique Cabrera"}},{"@type":"Person","@id":"https:\/\/robotica-facil-con-ros2.es\/?author=1#author","url":"https:\/\/robotica-facil-con-ros2.es\/?author=1","name":"Jose Enrique Cabrera","image":{"@type":"ImageObject","@id":"https:\/\/robotica-facil-con-ros2.es\/?p=6251#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/7fb8a5b8671a5fde1ab097847642f4ec46f3150e6ef27ed7fe4f7055bb02a052?s=96&d=mm&r=g","width":96,"height":96,"caption":"Jose Enrique Cabrera"}},{"@type":"WebPage","@id":"https:\/\/robotica-facil-con-ros2.es\/?p=6251#webpage","url":"https:\/\/robotica-facil-con-ros2.es\/?p=6251","name":"ROS2. Aprende c\u00f3mo usar servicios con Python -","description":"En este art\u00edculo aprender\u00e1s a comunicar dos nodos mediante un servicio usando Python.","inLanguage":"es-ES","isPartOf":{"@id":"https:\/\/robotica-facil-con-ros2.es\/#website"},"breadcrumb":{"@id":"https:\/\/robotica-facil-con-ros2.es\/?p=6251#breadcrumblist"},"author":{"@id":"https:\/\/robotica-facil-con-ros2.es\/?author=1#author"},"creator":{"@id":"https:\/\/robotica-facil-con-ros2.es\/?author=1#author"},"image":{"@type":"ImageObject","url":"https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png","@id":"https:\/\/robotica-facil-con-ros2.es\/?p=6251\/#mainImage","width":840,"height":426,"caption":"Servicios ROS2"},"primaryImageOfPage":{"@id":"https:\/\/robotica-facil-con-ros2.es\/?p=6251#mainImage"},"datePublished":"2022-09-15T15:32:54+00:00","dateModified":"2024-12-01T18:57:26+00:00"},{"@type":"WebSite","@id":"https:\/\/robotica-facil-con-ros2.es\/#website","url":"https:\/\/robotica-facil-con-ros2.es\/","description":"Rob\u00f3tica con ROS2","inLanguage":"es-ES","publisher":{"@id":"https:\/\/robotica-facil-con-ros2.es\/#person"}}]},"og:locale":"es_ES","og:site_name":"- ROS2. Aprende c\u00f3mo usar servicios con Python En este art\u00edculo aprender\u00e1s a comunicar dos nodos mediante un servicio usando Python.","og:type":"article","og:title":"ROS2. Aprende c\u00f3mo usar servicios con Python -","og:description":"En este art\u00edculo aprender\u00e1s a comunicar dos nodos mediante un servicio usando Python.","og:url":"https:\/\/robotica-facil-con-ros2.es\/?p=6251","og:image":"https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png","og:image:secure_url":"https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png","og:image:width":840,"og:image:height":426,"article:published_time":"2022-09-15T15:32:54+00:00","article:modified_time":"2024-12-01T18:57:26+00:00","twitter:card":"summary_large_image","twitter:site":"@RFconROS2","twitter:title":"ROS2. Aprende c\u00f3mo usar servicios con Python -","twitter:description":"En este art\u00edculo aprender\u00e1s a comunicar dos nodos mediante un servicio usando Python.","twitter:creator":"@RFconROS2","twitter:image":"https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png","twitter:label1":"Escrito por","twitter:data1":"Jose Enrique Cabrera","twitter:label2":"Tiempo de lectura estimado","twitter:data2":"13 minutos"},"aioseo_meta_data":{"post_id":"6251","title":null,"description":null,"keywords":[],"keyphrases":{"focus":{"keyphrase":null,"score":42,"analysis":{"keyphraseInTitle":{"title":"Focus keyphrase in SEO title","description":"Focus keyphrase not found in SEO title.","score":3,"maxScore":9,"error":1},"keyphraseInDescription":{"title":"Focus keyphrase in meta description","description":"Focus keyphrase not found in meta description.","score":3,"maxScore":9,"error":1},"keyphraseLength":{"title":"Focus keyphrase length","description":"Good job!","score":9,"maxScore":9,"error":0,"length":4},"keyphraseInURL":{"title":"Focus keyphrase in URL","description":"Focus keyphrase not found in the URL.","score":1,"maxScore":5,"error":1},"keyphraseInIntroduction":{"title":"Focus keyphrase in introduction","description":"Your Focus keyphrase does not appear in the first paragraph. Make sure the topic is clear immediately.","score":3,"maxScore":9,"error":1},"keyphraseInSubHeadings":{"title":"Focus keyphrase in Subheadings","description":"Use your focus keyphrase more in your H2 and H3 subheadings.","score":3,"maxScore":9,"error":1},"keyphraseInImageAlt":{"title":"Focus keyphrase in image alt attributes","description":"Focus keyphrase not found in image alt attribute(s). Add an image with your Focus keyphrase as alt text.","score":3,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":[],"twitter_use_og":true,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2022-09-15 15:45:50","updated":"2025-07-20 15:20:22","seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/robotica-facil-con-ros2.es\" title=\"Inicio\">Inicio<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/robotica-facil-con-ros2.es\/?cat=5\" title=\"ROS2\">ROS2<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tROS2. Aprende c\u00f3mo usar servicios con Python\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Inicio","link":"https:\/\/robotica-facil-con-ros2.es"},{"label":"ROS2","link":"https:\/\/robotica-facil-con-ros2.es\/?cat=5"},{"label":"ROS2. Aprende c\u00f3mo usar servicios con Python","link":"https:\/\/robotica-facil-con-ros2.es\/?p=6251"}],"rttpg_featured_image_url":{"full":["https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png",840,426,false],"landscape":["https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png",840,426,false],"portraits":["https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png",840,426,false],"thumbnail":["https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1-150x150.png",150,150,true],"medium":["https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1-300x152.png",300,152,true],"large":["https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png",840,426,false],"1536x1536":["https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png",840,426,false],"2048x2048":["https:\/\/robotica-facil-con-ros2.es\/wp-content\/uploads\/2022\/09\/Services-1.png",840,426,false]},"rttpg_author":{"display_name":"Jose Enrique Cabrera","author_link":"https:\/\/robotica-facil-con-ros2.es\/?author=1"},"rttpg_comment":0,"rttpg_category":"<a href=\"https:\/\/robotica-facil-con-ros2.es\/?cat=5\" rel=\"category\">ROS2<\/a>","rttpg_excerpt":"En este art\u00edculo aprender\u00e1s a comunicar dos nodos mediante un servicio usando Python.","_links":{"self":[{"href":"https:\/\/robotica-facil-con-ros2.es\/index.php?rest_route=\/wp\/v2\/posts\/6251","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/robotica-facil-con-ros2.es\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/robotica-facil-con-ros2.es\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/robotica-facil-con-ros2.es\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/robotica-facil-con-ros2.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6251"}],"version-history":[{"count":378,"href":"https:\/\/robotica-facil-con-ros2.es\/index.php?rest_route=\/wp\/v2\/posts\/6251\/revisions"}],"predecessor-version":[{"id":8127,"href":"https:\/\/robotica-facil-con-ros2.es\/index.php?rest_route=\/wp\/v2\/posts\/6251\/revisions\/8127"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/robotica-facil-con-ros2.es\/index.php?rest_route=\/wp\/v2\/media\/6611"}],"wp:attachment":[{"href":"https:\/\/robotica-facil-con-ros2.es\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6251"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/robotica-facil-con-ros2.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6251"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/robotica-facil-con-ros2.es\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6251"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}