---
# System prepended metadata

title: Tutorial introdutório ao ROS - LEAD

---

# Tutorial introdutório ao ROS - LEAD

[TOC]

## 0 - Introdução

Esse é um tutorial de como instalar o ROS2 Humble e o Gazebo, em um
container Distrobox, e como controlar um carrinho de exemplo pronto do
Gazebo com um controle remoto, usando o ROS2.

## 1 - Dependências básicas  

\- Instale Podman e Docker.

\- Documentação recomendada:

- <https://diolinux.com.br/tecnologia/configurar-instalar-distrobox.html>
- <https://distrobox.it/>

\- É recomendado estudar o básico de docker antes. Principalmente os
conceitos de imagem, conteiner, host, node, volume e containerfile.


\- Instalando o Distrobox:

```bash
~$ curl https://raw.githubusercontent.com/89luca89/distrobox/main/install | sudo sh
```  
- Baixa o script que instala o Distrobox e executa ele.  
  
### 1.1 - Criando seu rosBox

\- Criando uma imagem usando distrobox:  

```bash  
~$ distrobox-create --root --image docker.io/library ros:humble-ros-base-jammy --name humbleV2 --home ~/home/humbleV2
```

\- O comando acima cria uma imagem. As flags serão descritas abaixo:

- --root: instala como root
- --image: pega uma imagem específica para criar a nova imagem. Isso
  pode ser feito localmente ou busca da internet, fazendo um pull do
  docker hub. No caso estou pegando a imagem do docker-hub,
  humble-ros-base-jammy
- --name: específica um nome para a imagem. Isso é importante para
  referenciar de forma scriptável, porque se não especificar, será dado um
  nome aleatório.
- –home: conecta um diretório do host com a home da imagem usando a
  tecnologia de volumes. É necessário que o diretório exista antes.


- Levantando um container usando a imagem criada.  

```bash
~$ distrobox enter --root humbleV2  
~$ cd ~
```

- Atualizando o container:

```bash
~$ sudo apt update | sudo apt upgrade -y  
```

### 1.2 Instalando mais do ROS


- Instalando dependências do ROS e o próprio ROS (sim, é necessário):  
[https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html)

* (Poderia-se criar um dockerfile usando o tutorial, mas eu gosto mais de usar CLI mesmo)

```bash
~$ sudo apt install software-properties-common  
~$ sudo add-apt-repository universe
~$ sudo apt update | sudo apt upgrade -y  
~$ sudo apt install ros-humble-desktop  
~$ sudo apt install ros-humble-ros-base ros-dev-tools python3-pip  
```

- Instalando o colcon, o build que você usará para os seus pacotes  <https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Colcon-Tutorial.html><span id="anchor-3"></span>

```bash
~$ sudo apt install python3-colcon-common-extensions  
```

## 2 - 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
~$ mkdir -p ~/ros2_ws/src
```
- Organize os comandos do colcon e as variáveis de ambiente genéricas
do ROS2:
```bash  
~$ echo "source /opt/ros/humble/setup.bash" \>\> ~/.bashrc  
~$ echo "source /usr/share/colcon_cd/function/colcon_cd.sh" \>\> ~/.bashrc
~$ echo "export \_colcon_cd_root=/opt/ros/humble/" \>\> ~/.bashrc  
~$ echo "source/usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash" \>\> ~/.bashrc
``` 

- 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
~$ cd ~/ros2_ws/src  
~/ros2_ws/src$ source /opt/ros/humble/setup.bash  
~/ros2_ws/src$ ros2 pkg create --build-type ament_python --license Apache-2.0
meu_primeiro_pacote  
~/ros2_ws/src$ cd ./meu_primeiro_pacote/meu_primeiro_pacote/
```

- Aqui está feito o primeiro pacote. Precisamos então criar nosso
primeiro nó do nosso pacote:

### 2.1 Usando um nó ROS pronto (joy)

### 2.2 Criando um nó ROS

```bash
~ros2_ws/src$ touch node_pub_sub.py  
```

- Depois abrimos o arquivo criado e colocamos esse código python:
```python
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
from std_msgs.msg import Empty
from sensor_msgs.msg import Joy

pub = pubR = None
id = 0


def publish(x,z):
    global pub,pubR
    msg = Twist()
    msg.linear.x = x
    msg.angular.z = z
    if not ((pub is None)):
        pub.publish(msg)

    if not (pubR is None):
        if id == 1:
            msgR = Empty()
            pubR.publish(msgR)

def joyCallback(data):
    global id
    x = data.axes[1]
    z = data.axes[0]
    b = data.buttons[1]
    id = (b^id) and b
    publish(x,z)

def main(args=None):
    global pub, pubR
    
    rclpy.init(args=args)    
    node = Node("core")
    
    pub = node.create_publisher(Twist, '/demo/cmd_demo', 1)
    pubR = node.create_publisher(Empty,'/rpy/blink',1)
    
    node.create_subscription(Joy,'/joy',joyCallback,1)
    
    rclpy.spin(node)

main()
```

- Esse código será explicado no 2.3

Importante ressaltar aqui, é a função `joyCallback` que pega o `-data.axes[0]`. Depois verifique se é o eixo que você quer, porque isso muda de controle para controle.

```bash
~/ros2_ws/src/meu_primeiro_pacote/meu_primeiro_pacote$ cd ~/ros2_ws/
```

- Depois de feito isso você terá que mudar o arquivo “package.xml”,adicionando as dependencias do seu código. Ficando assim:

```xml
...

<license>Apache-2.0</license>
<exec_depend>rclpy</exec_depend>
<exec_depend>geometry_msgs</exec_depend>
<exec_depend>sensor_msgs</exec_depend>
<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>

...
```

- Adicionando 3 linhas na linha 10.

- E, por fim, você terá que modificar o setup.py:

```python
...

tests_require=['pytest'],
  entry_points={
    'console_scripts': [
      'pubSub = meu_primeiro_pacote.node_pub_sub: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
~$ cd ~
~$ pip3 install setuptools==58.2.0 
~$ rosdep update  
~$ rosdep install -i --from-path src --rosdistro humble -y*
```

Agora você já pode buildar seu nó. Para isso rode:

```bash
~$ colcon build --packages-select meu_primeiro_pacote --symlink-install
```
### 2.3 Explicando o código

#### 2.3.1 Raspberry Pi

## 3 Gazebo e execução

- Instalar o gazebo e abrir um modelo pronto.

```bash
~$ sudo apt install ros-humble-gazebo-ros-pkgs
~$ gazebo --verbose /opt/ros/humble/share/gazebo_plugins/worlds/gazebo_ros_diff_drive_demo.world*
```

- Com o gazebo aberto, em outro terminal rode o seu nó (pubSub).

```bash  
~$ distrobox-enter --root humbleV2
~$ source ros2_ws/install/setup.bash 
~$ ros2 run meu_primeiro_pacote pubSub
```

- Falta só o joy, rode em outro terminal:

```bash
~$ distrobox-enter --root humbleV2  
~$ ros2 run joy joy_node  
```

Com isso você já consegue controlar seu carrinho.

## 4 - Criando um roslaunch

- Agora criaremos um arquivo de launch, para rodar todos os programas necessários de uma só vez.

```bash
~$ cd ros2_ws/src/meu_primeiro_pacote
~/ros2_ws/src/meu_primeiro_pacote$ mkdir launch
~/ros2_ws/src/meu_primeiro_pacote/launch$ touch nodes_launch.py
```

- Agora abra o arquivo e coloque o seguinte código em python:

```python
from launch.actions import ExecuteProcess
from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():

    return LaunchDescription([
        ExecuteProcess(
            cmd=['gazebo', '--verbose', '/opt/ros/humble/share/gazebo_plugins/worlds/gazebo_ros_diff_drive_demo.world'],
            output='screen'
        ),
        Node(
            package = 'meu_primeiro_pacote',
            executable = 'pubSub',
            name = 'controle',
        ),
        Node(
            package = 'joy',
            executable = 'joy_node',
            name = 'node_joy',
        ),
        Node(
            package = 'meu_primeiro_pacote',
            executable = 'test_node',
            name = 'teclado',
        )   
    ])
```

- Temos agora que mexer nos arquivos e setup.py

```bash
 /launch$ cd ..
```
- Adicione as seguintes linhas no setup.py

```python
import os

...

data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
        (os.path.join('share', package_name, 'launch'), glob(os.path.join('launch', '*launch.[pxy][yma]*'))),
    ],

...
```

- Agora volte para o inicio do workspace e builde o pacote.

```bash
~/ros2_ws/src/meu_primeiro_pacote$ cd ..
~/ros2_ws/src$ cd ..
~/ros2_ws/$ colcon build --symlink-install
```

- Dê source na instalação

```bash
~/ros2_ws/$ source install/setup.bash.
```

- Você está pronto para executar o launch.

```bash
~/ros2_ws/$ ros2 launch meu_primeiro_pacote nodes_launch.py
``` 


1    - Ambiente
2    - Local 
2.1  - Key
2.2  - Gazebo
3    - Externo
3.1  - Joy/Gazebo
3.2  - Joy/Rasp

1- Ambiente
2- docker
3- ros
4- ws
5- pacotes
6- nos
7- topicos
8- msgs