# Capítulo 1 - Artigo 3 - Nó > Joy + publicador Vazio ## 3.0 - Introdução Até agora nós criamos um ambiente para o desenvolvimentos de projetos ROS e instalamos o ROS completamente. Nesse artigo veremos o funcionamento dos nós em ROS, e criaremos um publicador bem simples. ## 3.0.1 - Sumário Geral 1. Introdução do Capítulo 2. Instalando o ROS 3. Nó < Estamos aqui 4. Publicador 5. Subscritor 6. Raspberry Pi 7. Nó Raspberry Pi 8. Launch ## 3.0.2 - Sumário local [TOC] ## 3.1 - Analisando o funcionamento dos comandos ros2 topic - Conecte o joystick, o utilizaremos para analisar os comandos relacionados aos tópicos de ROS. - Simplesmente conectar o dispositivo não ativará seu funcionamento no ROS então temos que dar o seguinte comando. ```bash= user@host:~$ distrobox enter --root humbleV1 user@humbleV1:/home/USER$ ros2 run joy joy_node ``` - O comando ros2 run funciona da seguinte maneira: ros2 run [pacote] [nome do executável]. - Nesse caso, o comando ros2 run está inicializando o executável joy_node, dentro do pacote joy, esse pacote já vem junto com o ROS na instalação, deve ter a seguinte mensagem no seu terminal: ![image](https://hackmd.io/_uploads/SkQBYC42T.png) ### 3.1.1 ros2 topic list - Abra outro terminal, e dê os seguintes comandos para ver os tópicos que o nó joy inicializou. ```bash= user@host:~$ distrobox enter --root humbleV1 user@humbleV1:/home/USER$ ros2 topic list ``` - O comando acima lista todos os tópicos no qual seu ROS consegue ler, incluindo tópicos inicializados por outros dispositivos - Na sua tela os seguintes tópicos devem estar listados: ![image](https://hackmd.io/_uploads/HygiFA426.png) - Percebemos que o nó joy criou 2 tópicos, o /joy e o /joy/set_feedback ### 3.1.2 ros2 topic echo - No mesmo terminal dê o seguinte comando, ele lê as informações de um determinado tópico ```bash user@humbleV1:/home/USER$ ros2 topic echo /joy ``` - O funcionamento do comando é ros2 topic echo [topico a ser lido] - No seu terminal deve estar aparecendo a seguinte mensagem: ![image](https://hackmd.io/_uploads/r1Xq3CV2a.png) - Cada tópico tem seu tipo de mensagem, nesse caso, existe um header, com informações de tempo e id, existem os axes, que são os joysticks em si, e vão de -1 a 1, e existem os buttons que se referem aos botões do controle e tem apenas os valores 0 e 1. - Agora, aperte o botão "b" do controle e mexa o joystick esquerdo completamente para esquerda. ![image](https://hackmd.io/_uploads/Sy-wlyShT.png) - Repare que o primeiro elemento do axes mudou para 1, e o segundo do buttons também. ## 3.2 Criando um publicador simples - Agora criaremos um nó que publica vazio infinitamente. ### 3.2.1 Criando um workspace e um PKG - Crie um workspace. Esse será um ambiente para multiplos pacotes. O Workspace é um ambiente de desenvolvimento de um projeto. Um projeto pode ter diversos pacotes. ```bash= user@humbleV1:/home/USER$ mkdir -p ~/ros2_workspace/src ``` - Vamos agora criar um pacote [https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Creating-Your-First-ROS2-Package.html](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Creating-Your-First-ROS2-Package.html) ```bash user@humbleV1:/home/USER$ cd ~/ros2_workspace/src user@humbleV1:~/ros2_workspace/src$ source /opt/ros/humble/setup.bash user@humbleV1:~/ros2_workspace/src$ ros2 pkg create --build-type ament_python --license Apache-2.0 empty_pkg user@humbleV1:~/ros2_workspace/src$ cd empty_pkg/empty_pkg/ ``` - Feito o pacote. Precisamos então criar nosso nó. ### 3.2.2 Criando o nó que publica vazio - Dê o comando abaixo ```bash user@humbleV1:~/ros2_workspace/src/empty_pkg/empty_pkg$ touch node_pub_empty.py ``` - Depois abrimos o arquivo criado e colocamos esse código python: ```python=1 import rclpy import time from rclpy.node import Node from std_msgs.msg import Empty def publish(): msg = Empty() pub.publish(msg) def main(args=None): global pub rclpy.init(args=args) node = Node("empty_node") pub = node.create_publisher(Empty, '/empty', 1) while True: publish() time.sleep(1) main() ``` - O código será explicado nas próximas sessões - Depois de feito isso você terá que mudar o arquivo “package.xml”,adicionando as dependencias do seu código. Ele estará assim: ```xml=7 ... <license>Apache-2.0</license> <test_depend>ament_copyright</test_depend> ... ``` - terá que adicionar 2 linhas entre essas duas linhas, ficando assim: ```xml=7 ... <license>Apache-2.0</license> <exec_depend>rclpy</exec_depend> <exec_depend>std_msgs</exec_depend> <test_depend>ament_copyright</test_depend> <test_depend>ament_flake8</test_depend> ... ``` - E, por fim, você terá que modificar o setup.py: ```python!=1 ... tests_require=['pytest'], entry_points={ 'console_scripts': [ 'empty_node = empty_pkg.node_pub_empty:main', ], }, ) ``` - O setup.py é quem diz como o colcon irá construir seu nó. - Será necessário instalar as dependencias do seu programa agora. Também será necessário especificar uma biblioteca, pelo uso padrão do Humble. ```bash user@humbleV1:~/ros2_workspace$ pip3 install setuptools==58.2.0 user@humbleV1:~/ros2_workspace$ rosdep update user@humbleV1:~/ros2_workspace$ rosdep install -i --from-path src --rosdistro humble -y ``` - Agora você já pode buildar seu nó. Para isso rode: ```bash ~$ colcon build --symlink-install ``` ### 3.1.2 Rodando o Nó e verificando - Depois que seu pacote foi devidamente buildado, você poderá usar o ROS para chamar o seu nó publicador de teclado. ```bash user@humbleV1:~/ros2_workspace$ ros2 run empty_pkg empty_node ``` - Com outro terminal aberto, rode: ```bash user@host:~$ distrobox enter --root humbleV1 user@humbleV1:/home/USER$ ros2 topic list ``` - Depois que você rodar esse ultimo comando, deve parecer algo assim: ![image](https://hackmd.io/_uploads/HyGkaeHna.png) - Agora dê o seguinte comando para ler o tópico: ```bash user@humbleV1:/home/USER$ ros2 topic echo /pub_empty ``` ![image](https://hackmd.io/_uploads/rJ2z6lBnp.png) - Como podemos ver o publicador vazio está funcionando. ### 3.1.3 Explicando o código - Vamos agora explicar o código do publicador, iremos divir em 2 partes, a main e o publish. #### 3.1.3.1 main - Vamos começar entendendo a main, que possue o seguinte código: ```python= import rclpy import time from rclpy.node import Node from std_msgs.msg import Empty ``` ```python=11 def main(args=None): global pub rclpy.init(args=args) node = Node("empty_node") pub = node.create_publisher(Empty, '/pub_empty', 1) while True: publish() time.sleep(1) main() ``` - Da linha 1 a 4 estão as importações necessárias ao código. - A função main cria a variável global pub, inicia o ros, e cria o nó. - Na linha 17 o publicador é criado, com 3 variaveis de entrada, o tipo de mensagem que será publicada, no caso Empty, o nome do tópico a ser publicado, e também quantos tópicos publicará por vez. Se você deseja que o publicador crie uma fila de publicações, para depois publicar, basta aumentar o número. - Nas linhas 19 e 20 a função publish é chamada infinitamente, com um intervalo de 1 segundo entre os chamados. - Na linha 22 a função main é chamada. #### 3.1.3.2 publish - Agora analisaremos a função publish. ```python=6 def publish(): msg = Empty() pub.publish(msg) time.sleep(1) ``` - Na linha 7 criamos a mensagem a ser publicada, no caso um vazio. - Na linha 8 usamos o método publish para publicar nossa mensagem. ------- Agora você aprendeu como os nós funcionam no ROS2 e a escrever um nó publicador que publica mensagens vazias. Sua próxima tarefa é criar um subscitor. _______