# 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