# Capítulo 1 - Artigo 6 - Raspberry Pi ## 6.0 - Introdução O presente artigo tem como objetivo configurar o Raspberry Pi 4,presente no laboratório, para rodar o ROS2 seja em um container dentro do Raspberry Pi OS (64-bit), seja no Ubuntu 22.04 LTS (64-bit) e posteriormente rodar os pacotes que visam interagir com o LED que serão apresentados abaixo. ## 6.0.1 - Sumário Geral do capitulo 1 1. Introdução do Capítulo 2. Instalando o ROS 3. Nó 4. Publicador 5. Subscritor 6. Raspberry Pi < Estamos aqui 7. Nó Raspberry 8. Launch ## 6.0.2 - Sumário Local [TOC] ## 6.1 - Conhecendo o Raspberry Pi 4 O Raspberry Pi 4 possui como entradas de periférico mais relevantes 2 entradas mini HDMI, 1 entrada de alimentação USB-C, 4 entradas USB e uma entrada micro-SD conforme foto abaixo: ![image](https://hackmd.io/_uploads/BJNZnfd5T.png) O Raspberry em si não possui interface inicial de configuração e faz-se necessário a instalação de um sistema operacional no micro-SD através do [Raspberry Pi Imager](https://www.raspberrypi.com/software/), interface gráfica simples e oficial para isso, onde destrincharemos o passo a passo a seguir. ## 6.2 - Instalação do Sistema Operacional Antes de qualquer instalação é **IMPRESCINDíVEL** verificar o conteúdo presente no micro-SD uma vez que o processo de instalação da imagem deleta todo e qualquer arquivo presente no mesmo. Se houver algo no SD entrar em contato com o professor Jacoud ou outro responsável do laboratório. A interface gráfica do Raspberry Pi Imager tem às seguintes opções: ![image](https://hackmd.io/_uploads/HyfGCMO5a.png) No botão `Choose Device` você escolhe `Raspberry Pi 4` e em `Choose OS` o sistema operacional desejado, no caso, pode ser o `Raspberry Pi OS (64-bit)` ou em `Other general-purpose OS` e depois em `Ubuntu` e por último`Ubuntu Desktop 22.04.03 LTS (64-bit)`. Depois disso basta selecionar `NEXT` até que o processo de instalação comece e basta aguardar até o fim do processo para poder inicializar o raspberry e fazer as configurações iniciais do SO. Antes de acessarmos o SO se faz necessário o uso de um teclado, mouse e monitor para acessarmos o sistema operacioal e posteriormente habilitarmos o ssh (acesso remoto por terminal). Como mencionado anteriormente, recomendamos 2 opões de sistema operacional e iremos destrinchar o tutorial nas 2 opções propostas. ## 6.3 - Configuração inicial do Raspberry Pi OS A configuração do Raspberry Pi OS é bastante intuitiva no menu principal basta selecionar país, língua, fuso horário. Depois criar o usuário padrão, a rede wifi. Além disso, é necessário habilitar o ssh para conseguirmos acessar o raspberry através da rede direto do seu computador. ### 6.3.1 - Configurando ssh Para habilitar o ssh é necessário abrir a aba com o icone do raspberry, depois ir em `Preferences`, depois `Raspberry Pi Configuration`. Na aba que abriu ir em `Interfaces` e habilitar a opção de ssh. ### 6.3.2 - Conectando via ssh Para acessar o raspberry via ssh é necessário realizar o seguinte comando no computador: ```bash! ssh nomeDoUsuarioDoRaspberry@ip ``` Note que o `ip` é obtido utilizando o comando abaixo no raspberry: ```bash! hostname -I ``` ### 6.3.3 - Configurando um container com ROS2 Humble Como o ROS2 Humble roda nativamente no Ubuntu 22.04 o ideal é rodar nesse SO portanto vamos utilizar o distrobox que é um gerenciador de containers de distribuições que utiliza o docker ou o podman por baixo dos panos para criar um container isolado e seguro para rodarmos o ROS2 Humble. Para isso é necessário seguir os seguintes passos: ```bash! sudo apt-get install podman curl -y # Instala o podman e o curl sudo systemctl enable --now podman # Habilita o funcionamento do podman sudo reboot # Reinicia o raspberry ssh nomeDoUsuarioDoRaspberry@ip # faz ssh com o raspberry novamente curl https://raw.githubusercontent.com/89luca89/distrobox/main/install | sudo sh # Baixa o script que instala o Distrobox com o curl e o executa cd && mkdir containers # Criar a pasta containers na raiz do usuario cd containers && mkdir humbleV1 # Cria a pasta que guardaremos nosso container distrobox-create --root --image docker.io/library/ros:humble-ros-base-jammy --name humbleV1 --home ~/containers/humbleV1 # Cria o container humbleV1 com volume em ~/containers/humbleV1 distrobox enter --root humbleV1 # Entra no container criado sudo apt update | sudo apt upgrade -y # Atualiza o container echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc # Configura os terminais para reconhecer os comandos do ROS2 sempre que inicializar um terminal echo "source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash" >> ~/.bashrc # Configura os terminais para reconhecer os comandos do colcon sempre que inicializar um terminal source ~/.bashrc # "Reinicializando" o terminal ``` ## 6.3 - Configuração inicial do Ubuntu 22.04 LTS A configuração do Ubuntu no raspberry segue o mesmo padrão que a configuração em outros PCs. Depois de configurados o idioma, teclado, rede, região e usuário padrão conforme preferir, atualize os programas através dos comandos: ```bash! sudo apt update sudo apt upgrade ``` ### 6.3.1 - Configurando ssh Após as etapas anteriores é necessário habilitar o ssh para conseguirmos acessar o raspberry através da rede direto do seu computador. Para isso é necessário o seguinte conjunto de comandos: ```bash! sudo apt update # Verifica e atualiza os repostiórios dos programas do sistema sudo apt install openssh-server # Baixa o gerenciador do ssh sudo systemctl start ssh # Habilita o ssh sudo systemctl enable ssh # Habilita o ssh toda vez que o computador iniciar ``` Para verificar se tudo foi configurado corretamente basta usar o seguinte comando: ```bash! sudo systemctl status ssh # Verifica o status do ssh ``` Caso apareça algo parecido com a imagem abaxo, está tudo correto e basta precionar `q` para continuar. ![image](https://hackmd.io/_uploads/BJ3sBglj6.png) ### 6.3.2 - Conectando via ssh Feito oque foi descrito acima para acessar o raspberry via ssh é necessário realizar o seguinte comando no computador: ```bash! ssh nomeDoUsuarioDoRaspberry@ip ``` Note que o `ip` é obtido utilizando o comando abaixo no raspberry: ```bash! hostname -I ``` ### 6.4 - Instalando ROS2 e Colcon Agora só nos resta instalar o ROS2 Humble e suas dependências com os seguintes comandos: ```bash! sudo apt update && sudo apt install curl -y # Verifica os repositórios e instala o curl com a flag -y preenchendo com "yes" as possíveis perguntas sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg # Usa o curl para baixar a GPG key necessária para acessar o repositório do ROS2 echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null # Adiciona o repostório na source list para atualizações futuras sudo apt update # Verifica e atualiza os repostiórios dos programas do sistema sudo apt upgrade -y # Instala as versões dos respotirórios dos programas do sistema com a flag -y preenchendo com "yes" as possíveis perguntas sudo apt install ros-humble-ros-base -y # Instala a versão base do ROS2 Humble com a flag -y preenchendo com "yes" as possíveis perguntas echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc # Configura os terminais para reconhecer os comandos do ROS2 sempre que inicializar um terminal sudo apt install python3-colcon-common-extensions -y # Instala o colcon com a flag -y preenchendo com "yes" as possíveis perguntas echo "source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash" >> ~/.bashrc # Configura os terminais para reconhecer os comandos do colcon sempre que inicializar um terminal source ~/.bashrc # "Reinicializando" o terminal ``` Abaixo explicaremos como funciona o pacote criado para o Raspberry e suas peculiaridades em cada um dos SO's citados, mas antes é necessário fazer as ligações do LED com o Raspberry Pi. ## 6.5 - Ligação dos pinos no Raspberry Note o pinout do Raspberry: ![image](https://hackmd.io/_uploads/Sk8iWpyoa.png) --- **CUIDADO!! Preste MUITA atenção nessa parte pois um descuido na hora de ligar os pinos pode levar à queima do Raspberry** --- De acordo com os arquivos do pacote o pino inicialmente configurado para receber o sinal de liga e desliga do LED é a `GPIO17` sendo necessário a montagem do seguinte esquema: ![image](https://hackmd.io/_uploads/rJX2xakj6.png) ## 6.6 - Criação e configuração do pacote Blink Tutorial O pacote Blink Tutorial consiste em um pacote ROS2 que faz com que o LED pisque de diferentes formas. De forma análoga em ambos os sistemas operacionais podemos criar o workspace e o pacote através do ROS2 com os seguintes comandos: ```bash! sudo apt update # Verifica e atualiza os repostiórios dos programas do sistema cd && mkdir tutorial_ws # À partir do diretório raiz do usuario cria a pasta tutorial_ws cd tutorial_ws && mkdir src # Navega até a pasta tutorial_ws e cria a pasta src (source) colcon build # Configura o Workspace ROS echo "source ~/tutorial_ws/install/setup.bash" >> ~/.bashrc # Configura os terminais para reconhecer os comandos dos pacotes dentro do workspace source ~/.bashrc # "Reinicializando" o terminal sudo apt install python3-gpiozero -y # Instala a dependencia gpiozero que cuida da interface com as gpios do raspberry cd src && ros2 pkg create blink_tutorial --build-type ament_python --dependencies rclpy std_msgs gpiozero # Navega até a pasta src e cria o pacote blink_tutorial de linguagem python com as dependencias rclpy std_msgs gpiozero cd .. && colcon build # Retorna a pasta raiz do workspace e atualiza o workspace para incluir o pacote criado ``` Configurado o pacote podemos criar e configurar os nós como mostrado abaixo. ## 6.6 - Criação e configuração do Nó de teste de pinagens O nó de teste de pinagens serve para verificar se as bibliotecas de acesso a gpio e o esquemático estão corretamente configurados, alternando o estado do LED de acordo com o tempo estabelecido na criação do nó. ### 6.6.1 - Criação do Nó Para confeccionar esse nó fazemos o seguinte conjunto de comandos: ```bash! cd ~/tutorial_ws/src/blink_tutorial/blink_tutorial/ # Navega até a pasta ~/tutorial_ws/src/blink_tutorial/blink_tutorial/ onde devemos criar os códigos dos nós desse pacote touch blink_test.py # Criação do arquivo que conterá o código do nó de teste de pinagens chmod +x blink_test.py # Transformando esse arquivo em um executável ``` ### 6.6.2 - Configurando o Nó Agora precisamos editar o arquivo `~/tutorial_ws/src/blink_tutorial/setup.py` para adicionar um comando para executar esse nó. Particularmente eu gosto do vim para edição de arquivos no terminal mas se preferir pode usar o nano (o code nesse caso não abriria porque estamos por ssh e não temos acesso a interface gráfica mas se não estiver por ssh use o editor que preferir). Abaixo tem o conjunto de comandos necessários para instalar o vim e abrir esse arquivo. ```bash! sudo apt update # Verifica e atualiza os repositórios dos programas do sistema sudo apt install vim -y # Instala o vim com a flag -y preenchendo com "yes" as possíveis perguntas vim ~/tutorial_ws/src/blink_tutorial/setup.py # Abre ~/tutorial_ws/src/blink_tutorial/setup.py no vim ``` Ao executar esse comando temos a seguinte resposta: ```python= from setuptools import find_packages, setup package_name = 'blink_tutorial' setup( name=package_name, version='0.0.0', packages=find_packages(exclude=['test']), data_files=[ ('share/ament_index/resource_index/packages', ['resource/' + package_name]), ('share/' + package_name, ['package.xml']), ], install_requires=['setuptools'], zip_safe=True, maintainer='leadpi4-pios', maintainer_email='leadpi4-pios@todo.todo', description='TODO: Package description', license='TODO: License declaration', tests_require=['pytest'], entry_points={ 'console_scripts': [ ], }, ) ``` >Obs: Alguns comandos úteis do vim: >* `i` para ativar o modo de edição >* `esc` para sair do modo de edição >* `dd`para deletar uma linha (só funciona fora do modo de edição) >* `u` para desfazer a ultima modificacao (só funciona fora do modo de edição) >* `:wq` salva e sai (só funciona fora do modo de edição) >* `:q `sai (só funciona fora do modo de edição) Agora se quisermos adicionar esse nó como um executável de nome `blink_test` podemos editar `entry_points` da seguinte forma: ```python= from setuptools import find_packages, setup package_name = 'blink_tutorial' setup( name=package_name, version='0.0.0', packages=find_packages(exclude=['test']), data_files=[ ('share/ament_index/resource_index/packages', ['resource/' + package_name]), ('share/' + package_name, ['package.xml']), ], install_requires=['setuptools'], zip_safe=True, maintainer='leadpi4-pios', maintainer_email='leadpi4-pios@todo.todo', description='TODO: Package description', license='TODO: License declaration', tests_require=['pytest'], entry_points={ 'console_scripts': [ "blink_test= blink_tutorial.blink_test:main" ], }, ) ``` Basicamente oque fizemos foi configurar o nó executável `blink_test` como a execução da função `main` existente dentro do arquivo `blink_test` do pacote `blink_tutorial` Além disso, no caso do Ubuntu é necessário usar os comandos abaixos para termos acesso às GPIOs: ```bash! sudo adduser "${USER}" dialout # Adiciona o usuário ao grupo de acesso as GPIOs no Ubuntu sudo reboot # Reinicia o raspberry ``` Agora podemos editar tranquilamente o nó editando o arquivo `~/tutorial_ws/src/blink_tutorial/blink_tutorial/blink_test.py` e a cada necessidade de execução após edição desse arquivo é necessário dar um `colcon build` em `~/tutorial_ws/` para recompilar o pacote. ### 6.6.3 - Editando o Nó O código para esse nó está descrito abaixo, feito dessa vez com classes para termos uma outra perspectiva de implementação de um nó, sendo destrinchado em seguida: ```pyhton= #!/usr/bin/env python3 import rclpy from rclpy.node import Node from gpiozero import LED class BlinkNode(Node): def __init__(self): super().__init__(node_name="blink_test") self.create_timer(1,self.blink_callback) self.led = LED(17) def blink_callback(self): self.led.toggle() def main(args=None): rclpy.init(args=args) node = BlinkNode() rclpy.spin(node) rclpy.shutdown() ``` > . Na linha 1 configuramos o tipo de python que vamos usar > . Na linha 2 e 3 importamos a biblioteca do ROS2 em python a `rclpy` > . Na linha 4 importamos a biblioteca gpiozero de interação com as GPIOs > . Nas linhas 6 a 13 criamos uma classe `BlinkNode(Node)` que herda as características e métodos da classe `Node` do `rlcy` e criamos seu construtor `__init__()` nas linhas 7 a 10 e uma outra função `blink_callback()` nas linhas 12 a 13 que explicaremos abaixo. >> . Na linha 8 do construtor chamamos o construtor da classe que herdamos através do método `super().__init__()` inicializando-o com o nome do nó >> . Além disso na linha 9 nós criamos um timer através do método herdado `self.create_timer()` que a cada `1` segundo executará a função `blink_callback()` >> . Na linha 10 inicializamos um atributo chamado `led` inicializando como um objeto do tipo `LED` da lib `gpiozero` com o pino `17` >> . Na linha 12 e 13 criamos o método `blink_callback()` que utiliza o método `toggle()` da classe `LED` que alterna o estado anterior do led no pino 17 >> > . Da linha 15 a 19 criamos a função `main` que inicializa o ROS2 e o nó >> . Na linha 16 inicializamos o ROS2 >> . Na linha 17 criamos o nó à partir da classe `BlinkNode()` >> . Na linha 18 mantemos o nó ativo através do uso do método `spin()` >> . Por fim na linha 19 finalizamos o ROS2 Não se esqueça do `colcon build` em `~/tutorial_ws/` para recompilar o pacote. Se tudo der certo o LED deverá piscar de 1 em 1 segundo e se desejar mudar esse tempo basta alterar o valor `1` do primeiro argumento do método `create_timer()`. ## 6.4 - Erros comuns no Raspberry Pi OS ## 6.4 - Erros comuns no Ubuntu 22.04 ### 6.4.1.Problemas com gpiozero ![image](https://hackmd.io/_uploads/BkeXuzesa.png) > O erro indica que não foi possível encontrar uma biblioteca padrão de interação com os pinos ou ![image](https://hackmd.io/_uploads/B1yf6GWjp.png) > O erro indica que não foi possível ter acesso aos pinos O gpiozero é uma lib que intermedia a interação com as gpios de maneira mais amigável e genérica que as interfaces providas pelos sistemas operacionais, portanto ela interage por debaixo dos panos com a biblioteca do SO responsável por prover interação com as gpios e normalmente essa lib precisa de acesso root, abaixo soluções para esse problema: * Use o conjunto de comandos abaixo: ```bash! sudo adduser "${USER}" dialout # Adiciona o usuário ao grupo de acesso as GPIOs no Ubuntu sudo reboot # Reinicia o raspberry ``` * Caso o problema persista use o seguinte comando: ```bash! export GPIOZERO_PIN_FACTORY=lgpio # Configura a biblioteca a ser utilizada por baixo dos panos pela gpiozero ```