---
# System prepended metadata

title: Cap1 - Art 3 - Nó
tags: [Apostila de Introdução Geral no LEAD - 2024]

---

# 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.
_______