diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..75dfd09 --- /dev/null +++ b/404.html @@ -0,0 +1,1423 @@ + + + +
+ + + + + + + + + + + + + + +Para que seja possível desenvolver programas que controlem os robôs, é necessário instalar o SDK (Software Development Kit - Kit de Desenvolvimento de Software) do NAO v4 para C++.
+Esse SDK possui APIs e pacotes importantes para o desenvolvimento de tais programas.
+Para verificar a versão do compilador GCC instalado na sua máquina, execute o comando:
+gcc --version
+
Caso o GCC não esteja instalado no seu sistema, execute:
+sudo apt update
+sudo apt install build-essential
+
gcc --version
+
O qiBuild é uma ferramenta para criar projetos entre sistemas operacionais diversos usando o CMake e será necessário para o propósito do presente tutorial.
+Dependências são pacotes necessários para rodar um programa específico. No caso, para instalar o qiBuild serão necessários os seguintes pacotes:
+sudo apt update
+sudo apt install build-essential cmake python-pip
+pip install 'pip==20.3.4'
+
++Obs.: Você provavelmente receberá warnings do pip no seu terminal, sugerindo o upgrade do pip. Apenas ignore esse aviso, pois o referido upgrade pode corromper o pip.
+
Para instalar o qiBuild, execute o seguinte código no terminal:
+pip install qibuild --user
+
Digite o código abaixo. Você deverá escolher o gerador (recomendado usar o Unix Makefiles) e o compilador de sua escolha.
+qibuild config --wizard
+
++Para os testes do presente tutorial, deixar o compilador como "None" não implicará em problemas. Além disso, você sempre pode reconfigurar seu qiBuild executando o código abaixo no diretório padrão "/~".
+
Resultado: um arquivo é criado em ~/.config/qi/qibuild.xml
. Ele será compartilhado por todas as worktrees que você criar.
++Obs.: worktrees são ambientes de trabalho, nesse caso, do qiBuild.
+
++Exemplo de caminho: "~/Downloads/worktree"
+Obs.: NÃO criar worktree em diretórios com acentos ortográficos no nome, pois isso gera erro de decodificação com o qiBuild.
+
cd caminho/para/worktree
+
qibuild init
+
Para baixar o SDK de C++, siga os seguintes passos:
+Former Versions
.++Obs.: Muito cuidado ao selecionar a opção correta de acordo com seu sistema operacional.
+
Extraia o arquivo baixado na worktree criada anteriormente.
+Supondo que o nome do arquivo extraído seja "naoqi-sdk-2.1.4.13-linux64", acesse o seguinte diretório:
+cd caminho/para/worktree/naoqi-sdk-2.1.4.13-linux64/doc/dev/cpp/examples
+
$ qitoolchain create minhatoolchain /caminho/para/naoqi-sdk-2.1.4.13-linux64/toolchain.xml
+
Em "minhatoolchain", deve ser inserido um nome de sua preferência.
+qibuild add-config minhatoolchain -t minhatoolchain --default
+
cd core/sayhelloworld
+echo "set(CMAKE_CXX_FLAGS "-D_GLIBCXX_USE_CXX11_ABI=0")" >> CMakeLists.txt
+
qibuild configure
+qibuild make
+
cd build-minhatoolchain/sdk/bin
+./sayhelloworld "Olá"
+
++ +Caso o binário rode e resulte no erro "Cannot connect to tcp://Olá:9559", o SDK foi instalado com sucesso.
+
Para que seja possível desenvolver programas que controlem os robôs, é necessário instalar o SDK (Software Development Kit - Kit de Desenvolvimento de Software) de C++ para o NAO v6 (com NAOqi 2.8).
+Esse SDK possui APIs e pacotes importantes para o desenvolvimento de tais programas.
+Para verificar a versão do compilador GCC instalado na sua máquina, execute o comando:
+gcc --version
+
Caso o GCC não esteja instalado no seu sistema, execute:
+sudo apt update
+sudo apt install build-essential
+
gcc --version
+
O qiBuild é uma ferramenta para criar projetos entre sistemas operacionais diversos usando o CMake e será necessário para o propósito do presente tutorial.
+Dependências são pacotes necessários para rodar um programa específico. No caso, para instalar o qiBuild serão necessários os seguintes pacotes:
+sudo apt update
+sudo apt install build-essential cmake python-pip
+
+# Atualizando versão do pip para última versão de suporte ao Python 2.7
+pip install 'pip==20.3.4'
+
Para instalar o qiBuild, execute o seguinte código no terminal:
+pip2 install qibuild --user
+
++Obs.: NÃO ATUALIZAR PIP AUTOMATICAMENTE (COMO SUGERE O PIP no TERMINAL) (o suporte do pip ao Python 2 chegou ao fim, sua atualização automática corrompe o Python 2 do sistema);
+
Digite o seguinte código. Você deverá escolher o gerador (recomendado usar o Unix Makefiles) e o compilador de sua escolha.
+qibuild config --wizard
+
Resultado: um arquivo é criado em ~/.config/qi/qibuild.xml
. Ele será compartilhado por todas as worktrees que você criar.
++Obs.: worktrees são ambientes de trabalho, nesse caso, do qiBuild.
+
++Exemplo de caminho: "/Área de Trabalho/worktree"
+
cd 'Área de Trabalho'/worktree
+
qibuild init
+
Nativamente, existe um exemplo testável intrínseco ao qiBuild, e vamos usá-lo para testar a instalação correta da ferramenta.
+qisrc create myFirstExample
+
cd myfirstexample
+
qibuild configure
+
++Obs.: note que o diretório
+build-sys-linux-x86_64
foi criado dentro do diretório "myfirstexample"
qibuild make
+
build-sys-linux-x86_64/sdk/bin
:cd build-sys-linux-x86_64/sdk/bin
+
E execute:
+./my_first_example
+
++Se a mensagem "Hello, world" aparecer no terminal, a instalação do qiBuild foi concluída com sucesso.
+
Para baixar o SDK de C++, siga os seguintes passos:
+Salvar arquivo
++Obs.: Muito cuidado ao selecionar a opção correta de acordo com seu sistema operacional.
+
Extraia o arquivo baixado no local de preferência
+Supondo que o nome do arquivo extraído seja "naoqi-sdk-2.8.5.10-linux64", crie um toolchain com o seguinte código (adicione o caminho para a pasta extraída e substitua no código abaixo):
+$ qitoolchain create minhatoolchain /caminho/para/naoqi-sdk-2.8.5.10-linux64/toolchain.xml
+
Em "minhatoolchain", deve ser inserido um nome de sua preferência.
+cd caminho/para/worktree
+
qibuild add-config myconfig -t minhatoolchain --default
+
++ +Lembre-se de trocar "minhatoolchain" pelo nome criado anteriormente.
+
Choregraphe é um programa da Softbank Robotics usado para:
+Com o Choregraphe, também é possível criar aplicativos contendo diálogos, serviços e comportamentos poderosos, como interação com pessoas, dança, envio de e-mails, com a possibilidade de desenvolvê-los sem escrever uma única linha de código.
+Mínimo
+Recomendado
+Sistema Operacional
+Ainda que o Choregraphe seja multiplataforma, recomenda-se a instalação no Ubuntu 16.04 (Xenial Xerus) - 64 bits.
+Para baixar o Choregraphe 2.1.4, acesse o site da Aldebaran Robotics.
+Desça até o sub-menu Choregraphe, e na seção do LINUX, clique em Former versions
.
Na página que se abre, selecione o setup do Choregraphe na versão 2.1.4 (versão usada com o NAO v4).
+O download será iniciado.
+Com o navegador de arquivos do Ubuntu, navegue até o diretório onde o setup baixado se encontra.
+Clique no arquivo de setup com o botão direito do mouse, vá em propriedades
e selecione a aba permissões
.
Marque a caixa Permitir a execução desse arquivo como um programa
.
No terminal, abra o diretório onde o setup foi baixado.
+Execute o setup com o seguinte código (supondo que o nome do arquivo baixado seja "choregraphe-suite-2.1.4.13-linux64-setup.run"):
+sudo ./choregraphe-suite-2.1.4.13-linux64-setup.run
+
No wizard que se abre, aceite as permissões, selecione a opção Quick install e, quando for pedida a license key, insira o seguinte código:
+++654e-4564-153c-6518-2f44-7562-206e-4c60-5f47-5f45
+
Finish
.++Obs.: Como alternativa ao processo de instalação manual, pode-se executar o seguinte código:
+
sudo ./choregraphe-suite-2.1.4.13-linux64-setup.run --mode unattended --installdir '/my/destination_directory' --licenseKeyMode licenseKey --licenseKey '654e-4564-153c-6518-2f44-7562-206e-4c60-5f47-5f45'
+
Executando o Choregraphe 2.1.4
+Para executar o Choregraphe 2.1.4, existem duas maneiras diferentes.
+++Clique duas vezes no ícone do Choregraphe.
+
++Execute o seguinte código:
+"/opt/Aldebaran Robotics/Choregraphe Suite 2.1/bin/choregraphe_launcher"
(com as aspas).
Caso a seguinte janela se abra, parabéns! Você instalou o Choregraphe 2.1.4 com sucesso.
+Choregraphe é um programa da Softbank Robotics usado para:
+Com o Choregraphe, também é possível criar aplicativos contendo diálogos, serviços e comportamentos poderosos, como interação com pessoas, dança, envio de e-mails, com a possibilidade de desenvolvê-los sem escrever uma única linha de código.
+Mínimo
+Recomendado
+Sistema Operacional
+Ainda que o Choregraphe seja multiplataforma, recomenda-se a instalação no Ubuntu 16.04 (Xenial Xerus) - 64 bits.
+Para baixar o Choregraphe 2.8.7, acesse o site da Aldebaran Robotics.
+Desça até o sub-menu Choregraphe, e na seção "LINUX (2.8.7 and later)", selecione Choregraphe 2.8.7 - Binaries
.
Quando o download for concluído, extraia o arquivo tar.gz no diretório de sua escolha.
+++Obs.: O setup está com arquivos corrompidos. É altamente recomendado que você baixe os binários. +Obs.: O arquivo de binários dispensa uma instalação formal, sendo necessário apenas executar o launcher do programa, conforme explicado abaixo.
+
Executando o Choregraphe 2.8.7
+Exemplo: se o arquivo extraído (choregraphe-suite-2.8.7.23-linux64
) está em "/meu/diretorio", execute o Choregraphe com:
"/meu/diretorio/choregraphe-suite-2.8.7.23-linux64/bin/choregraphe_launcher"
+
++IMPORTANTE: lembre-se de alterar o caminho no código acima de acordo com o local de extração do tar.gz dos binários baixados!
+
Selecionando o robô virtual NAO
+Connect to...
).Select
.Edit
e em Preferences
.NAO H25 (V6)
e clique em OK
. Na janela que se abre, confirme.CASO TENHA ERRO DE DESCONEXÃO DO ROBÔ
+Preferences
.Connect to...
.++ +Nota: +Você pode ter problemas com aceleração gráfica se não tiver com os drivers apropriados. Nesse caso, utilize: +
+./choregraphe --no-ogre
Antes de qualquer outro guia da Robo Connection, é importante entender alguns conceitos importantes sobre Terminal do Linux e Scripts. Esses conceitos servirão como ferramentas na conclusão de passos importantes para a programação do NAO.
+O terminal ou linha de comando do Linux é a interface onde os comandos de controle do sistema serão inseridos. Através dele, podemos instalar, desinstalar e atualizar programas, além de podermos navegar pelos diretórios do sistema.
+Como um computador funciona?
+O computador sempre executa códigos na linha de comando. Quando clicamos em botões e funcionalidades na tela, um processo acontece através de comandos que rodam no terminal sem que saibamos. Isso traz comodidade ao usuário, que nem sempre deseja saber o que ocorre por trás dos panos.
+Usando o terminal:
+Para abri-lo, aperte simultaneamente CTRL
+ALT
+T
.
Uma tela semelhante a essa se abrirá:
+No terminal de exemplo acima:
+gustavo@gustavo-Latitude-3420
(em verde): identifica o usuário e o apelido da máquina usada, respectivamente;~
(em azul): indica o diretório atual. No terminal, '~' equivale ao diretório /home/usuario/
.Um diretório nada mais é do que uma pasta. Todo diretório ou arquivo possui um caminho. Mas o que isso significa? +Isso significa que, se navegarmos por esse caminho, podemos chegar ao arquivo em questão.
+Por exemplo: se quero chegar ao diretório /home/usuário/
, posso sair de /
, acessar /home/
e depois acessar /home/usuário/
.
Conhecendo o pip:
+O pip é o instalador de pacotes do Python. Através dele, podemos instalar pacotes que usaremos na programação do NAO.
+A sintaxe de uso do pip para instalação de programas é pip install <pacote>
.
Em suma, o terminal permite a execução de programas de diversas linguagens, instalação de pacotes, edição de texto, dentre outras possibilidades.
+Comando ls
: listando arquivos
Para ver os arquivos presentes na pasta atual, podemos digitar o comando ls
. Essa ação irá gerar uma lista de arquivos e pastas que se encontram no diretório atual.
Por exemplo:
+No exemplo acima, usamos o comando ls
no diretório ~
(no caso, /home/gustavo/
). Isso gerou uma lista de arquivos presentes nesse diretório.
Note também que os arquivos em azul são diretórios (pastas). O arquivo em branco possui outro formato.
+Comando cd
: navegando entre diretórios
Para navegar entre diretórios no terminal Linux, usamos o comando cd <diretório>.
Para voltarmos para o diretório "mãe", usamos o comando cd ..
.
Por exemplo:
+No exemplo acima, usamos o comando ls
para listar os arquivos em ~
. Depois, usamos cd Downloads
para acessar o diretório ~/Downloads/
. Em seguida, usamos o cd ..
para retornarmos para o diretório "mãe". Ou seja, voltamos para ~
.
Assim, podemos usar o terminal do Linux para navegar em qualquer diretório do sistema.
+++Nota: para acessar diretórios com nomes que contenham espaços (como "Área de Trabalho"), sempre use aspas. Se quero acessar
+~/Área de Trabalho/
, devo usar o comandocd ~/'Área de Trabalho'
OBS.: Podemos acessar caminhos mais profundos de uma vez usando o comando cd
.
Por exemplo: dentro de ~
existe o diretório Downloads
. Dentro de Downloads
existe um diretório de nome Exemplo
. Portanto, o caminho desse diretório é ~/Downloads/Exemplo
.
Para chegarmos em ~/Downloads/Exemplo
, não precisamos acessar pasta a pasta. Podemos acessá-lo de qualquer diretório simplesmente usando o comando cd ~/Downloads/Exemplo
.
No exemplo acima, estávamos no diretório ~/Área de Trabalho/
. Usando o comando cd ~/Downloads/Exemplo
, acessamos esse diretório diretamente.
Comando clear
: limpando o terminal
Podemos usar esse comando para limpar o terminal. Basta digitar clear
na linha de comando e apertar ENTER
. Com isso, o terminal será limpo. Isso não muda o diretório atual.
O que são scripts?
+Scripts são instruções em sequência que executam alguma ação. Geralmente, utilizam um shell para executarem tais ações. +Um shell é uma ponte entre o usuário e o sistema operacional. Através do shell, o usuário acessa as funcionalidades do sistema operacional. Um shell pode ser de dois tipos:
+Assim, no seguimento dos tutoriais da Robo Connection, utilizaremos o Bash como linguagem de comando, sendo este o shell CLI padrão do Linux.
+Os scripts bash possuem a extensão ".sh".
+Ok, mas como executar um script?
+Suponha que queremos executar um script que está em ~/Downloads/
. Seu nome é meuscript.sh
. Esse script imprime "Hello World" na tela.
Para executar o script, precisamos seguir os seguintes passos:
+cd
. No caso, usamos cd ~/Downloads/
.chmod +x <nome_do_script>
. No exemplo, usamos chmod +x meuscript.sh
.sudo ./<nome_do_script>
. No exemplo, usamos sudo ./meuscript.sh
.++Nota: a permissão de superuser (ou sudo) é análogo ao ato de executar um programa como administrador (Windows). Isso garante que não haverão falhas de permissão na execução do programa. Alguns programas exigirão a permissão sudo para serem executados.
+
A linguagem de programação C++ é uma extensão à linguagem C. Através dessa extensão, a programação orientada a objetos se tornou possível.
+Em comparação ao Python, a linguagem C (e, consequentemente, o C++) é bem mais rápida em tempo de execução. Isso significa que um código para o NAO feito em Python vai ser executado pelo robô muito mais lentamente em comparação ao mesmo código em C++. Entretanto, o C++ possui uma sintaxe um pouco mais complicada e minuciosa em comparação ao Python.
+A orientação a objetos é um paradigma de programação. Para que você entenda melhor, faremos uma analogia. É como se fosse um video-game. Se você criasse um console de video-game, construiria um aparelho com diversos atributos, como os circuitos internos, que não devem ser acessados pelo usuário (privado). Em contrapartida, disponibilizaria métodos de acesso às funcionalidades do video-game pelo usuário (público), como botões em um joystick que o controla.
+A esse conceito damos o nome de interface. Uma interface nada mais é do que a "casca" que isola os componentes internos (como os circuitos internos) e os componentes externos do software (como o joystick, no exemplo). Internamente, a interface possui partes que devem estar privadas ao usuário. Externamente, possui partes que podem ser usadas pelo usuário, ou seja, estão públicas.
+Em relação às permissões de uso, damos o nome de encapsulamento. Podemos ter o encapsulamento privado (apenas o video-game controla suas partes internas, e não o usuário) e o encapsulamento público (o usuário controla as partes internas do video-game pelos botões da interface). Além desses dois tipos, possuímos o encapsulamento protegido, que não está no escopo desse guia.
+Uma classe é uma estrutura essencial quando tratamos de POO. Usaremos um exemplo para tornar esse conceito mais claro. Se considerarmos uma classe Pessoa, podemos pensar em atributos (dados) que todas as pessoas têm. Todas as pessoas possuem um nome, uma idade, uma altura e um peso. Esses serão os atributos da nossa classe Pessoa
.
Um objeto é uma instância da classe. Mas o que isso significa na prática? Se temos a classe Pessoa
, posso criar um objeto chamado pessoa1
da classe Pessoa
, que tenha nome "João", idade 33, altura 1,78m e peso 82,5kg. Em outras palavras, um objeto que instancia a classe Pessoa
é um exemplar da classe Pessoa
. Assim, o objeto terá os atributos exigidos pela classe, além de ter acesso aos métodos que estão nessa classe. Uma classe define, portanto, os atributos e métodos dos objetos que a instanciarão.
Resgatando a analogia do video-game, o objeto é o joystick, plataforma pela qual o usuário acessará e manipulará, indiretamente, os atributos da classe (circuito interno do video-game), que estão privados ao usuário. A classe, por sua vez, representa todo o video-game.
+++Obs.: Em uma classe, os atributos devem ser privados (não acessíveis ao usuário).
+
Para construir uma classe Pessoa
que possua os atributos acima, podemos utilizar o C++ da seguinte forma:
#include <iostream>
+using namespace std;
+
+class Pessoa{
+ // Aqui vamos colocar os atributos da classe
+ // Usamos "private" para declarar encapsulamento privado
+ private:
+ char nome[50];
+ int idade;
+ float altura;
+ float peso;
+
+ // Aqui vamos colocar os métodos da classe
+ // Usamos "public" para declarar encapsulamento público
+ public:
+ void inicializa_classe(char* name, int age, float height, float weight){
+ nome = name;
+ idade = age;
+ altura = height;
+ peso = weight;
+ };
+};
+
+int main(void){
+ Pessoa pessoa1;
+
+ // Abaixo, colocamos os valores passados como parâmetros nos atributos de pessoa1
+ pessoa1.inicializa("João", 33, 1.78, 82.5);
+
+ return 0;
+}
+
Na parte privada da classe Pessoa
, definimos os atributos (também chamados de membros). Na parte pública, criamos um método inicializa
que coloca valores nos atributos.
Em seguida, na função main, criamos o objeto pessoa1
da classe Pessoa
. Através desse objeto, utilizamos o método inicializa
, definido dentro da classe Pessoa
como um método público, ou seja, o usuário pode utilizar através do objeto.
A sintaxe para utilizar um método através do objeto de uma classe em C++ é: objeto.metodo(parametro1, parametro2, ...)
. Nesse caso, utilizamos pessoa1.inicializa("João", 33, 1.78, 82.5)
.
Ok, mas o que podemos fazer com os atributos?
+Para responder essa questão, temos que analisar as especificidades de nossa classe. No caso de Pessoa
, suponha que estamos usando essa classe para cadastrar pessoas em um sistema de uma rede de academias. Cada pessoa cadastrada deverá ter seu nome, idade, altura e peso registrados para melhor acompanhamento.
Além de armazenar informações, podemos utilizar a POO para realizar operações utilizando os atributos. A classe Pessoa
pode, por exemplo, ter um método que calcule e imprima o IMC dos clientes da academia, baseada nos atributos. Um outro método poderia calcular uma previsão de peso corporal caso a pessoa frequente a academia por certo período.
Assim, fica claro que a POO pode ajudar bastante na organização de sistemas. O NAO utiliza esse paradigma para organizar suas classes e métodos, realizando operações no robô através de objetos de classes diversas.
+Getters e Setters
+Exemplo:
+Maria, de 19 anos, foi cadastrada com 1.60m de altura e 63kg de peso. Porém, após o primeiro mês de academia, Maria perdeu 3kg. Além disso, mediu sua altura novamente e percebeu que possuía, na verdade, 1.62m de altura.
+Portanto, precisamos mudar esses atributos no objeto de Maria. Porém, os atributos são privados na classe Pessoa
. Isso significa que o objeto não pode acessar diretamente os atributos da classe. Por conta disso, precisamos de um método público dentro da classe, que possa mudar esses atributos.
Dessa forma, o objeto NÃO está acessando diretamente o atributo da classe, mas sim indiretamente, através de um método que, por sua vez, acessa diretamente esses atributos, evitando problemas de permissão.
+Observe o esquemático a seguir:
+Faremos isso utilizando getters e setters. Os métodos get e set são muito usadas na POO. Mas não se assuste, são métodos como qualquer outro. A única diferença é que nomeamos os métodos dessa forma padronizada. Esses métodos serão os mediadores entre o objeto e os atributos. Confira a seguir o seu uso:
+nome = objeto.get_nome()
.set: muda o valor de um atributo. Exemplo: objeto.set_idade(20)
.
No exemplo do get, colocamos na variável "nome" o valor retornado pelo método get_nome() de objeto
.
Então, para resolvermos o problema de Maria, cujos dados estão errados, basta utilizarmos métodos setters e getters para consertarmos, certo? Vamos fazer isso no bloco de código a seguir:
+Parte pública da classe Pessoa
:
public:
+ void inicializa_classe(char* name, int age, float height, float weight){
+ nome = name;
+ idade = age;
+ altura = height;
+ peso = weight;
+ };
+
+ float get_altura()
+ return altura;
+
+ float get_peso()
+ return peso;
+
+ void set_altura(float h)
+ altura = h;
+
+ void set_peso(float w)
+ peso = w;
+
Assim, completamos o seguinte diagrama para a classe Pessoa
:
Programa principal:
+int main(void){
+ Pessoa maria;
+
+ maria.inicializa("Maria", 19, 1.60, 63); // valores antigos
+
+ cout << "A altura de Maria atualmente e: " << maria.get_altura() << endl;
+ cout << "O peso de Maria atualmente e: " << maria.get_peso() << endl;
+
+ maria.set_altura(1.62); // arrumando altura
+ maria.set_peso(60); // arrumando peso
+
+ cout << "A nova altura de Maria e: " << maria.get_altura() << endl;
+ cout << "O novo peso de Maria e: " << maria.get_peso() << endl;
+
+ return 0;
+}
+
++Aqui, mostramos apenas a parte pública da classe e o programa principal, para fins didáticos. O resto da classe (parte privada) ainda existe!
+
Mas e agora, qual é o próximo passo?
+Para programar o NAO, é necessário que você entenda os conceitos apresentados nesse guia. O NAO utiliza métodos que pertencem a classes definidas pelos desenvolvedores do robô.
+Além disso, você também pode criar novas classes com métodos que podem, inclusive, utilizar métodos de outras classes.
+Dessa forma, o(a) incentivamos a continuar aprofundando seus estudos em POO (faça cursos para se aprofundar!), na interface do NAO e no SDK (Software Development Kit) do NAO (consulte nossos guias).
+Os robôs NAO utilizam diversos programas para configuração, programação e manutenção. Porém, esses programas são compatíveis com diferentes versões do sistema Linux.
+Para que não seja necessário utilizar muitas máquinas, utilizaremos apenas uma máquina com diversas máquinas virtuais (VMs) disponíveis para rodar no sistema com o gerenciador Virt Manager (cada máquina virtual com um sistema operacional diferente, para que sejam acessados os diversos programas em uma mesma máquina física).
+Para ilustrar a diferença dos sistemas operacionais necessários na operação dos NAOs, observe a tabela abaixo, onde são mostrados programas comuns usados na programação dos NAO v6.
+Programa | +Sistema Compatível | +
---|---|
Robot Settings 2.8.6 | +Ubuntu 16.04 | +
Choregraphe 2.8.6 | +Ubuntu 16.04 | +
NAOqi SDK 2.8.5 (C++ - V6) | +Ubuntu 16.04 | +
NAOqi SDK 2.1.4 (C++ - V4) | +Ubuntu 12.04 | +
ROS1 | +Ubuntu 20.04 | +
ROS2 | +Ubuntu 22.04 | +
++O NAO v4 utiliza diferentes versões desses programas, com sistemas operacionais também diferentes, em alguns casos. Para mais informações, consulte o Developer Center da Aldebaran Robotics.
+
O Virt Manager é o programa no qual as VMs estarão acessíveis, tornando possível criar, excluir e modificar VMs. Além disso, o Virt Manager permite o compartilhamento de portas USB entre máquina real e virtual e a criação de snapshots (pontos de controle), que funcionam como um recurso de back-up rápido caso estejamos testando diferentes funcionalidades que podem corromper o sistema das VMs.
+Para verificar a compatibilidade do processador, pode-se executar o comando kvm-ok
do pacote cpu-checker
como superuser.
sudo apt update
+sudo apt install cpu-checker
+sudo kvm-ok
+
Para instalar as dependências necessárias, execute o seguinte código em terminal:
+sudo apt update
+sudo apt install qemu-system-x86
+sudo apt install qemu-system-gui
+sudo apt install qemu-utils
+sudo apt install qemu-block-extra
+sudo apt install ovmf
+sudo apt install libguestfs-tools
+sudo apt install virt-manager
+
Habilitando o libvirtd
+sudo systemctl start libvirtd
+sudo systemctl enable libvirtd
+
++Obs.: necessário reiniciar o sistema após esse passo.
+
Forward
. No próximo menu, clique em Navegar
e procure a opção Navegar localmente
Sim
Concluir
para criar a VMPara iniciar a VM, clique duas vezes sobre a listagem da VM no menu principal do Virt Manager.
+Em seguida, clique no botão indicado para inicializar a máquina virtual selecionada:
+++A presente seção do tutorial se refere à uma instalação genérica de sistemas Ubuntu Linux. Caso seja necessário, consulte um guia de instalação da sua versão.
+
Com a VM iniciada, realize a instalação do Ubuntu normalmente:
+Instalar o Ubuntu
Instalar agora
e em seguida em Continuar
Continuar
e aguarde até o fim da instalaçãoReiniciar agora
++Obs.: após o reinício pós-instalação, é comum as VMs travarem. Se for o caso, no menu superior do Virt Manager há um botão vermelho com uma seta ao lado. Clique na seta e selecione "Forçar desligamento". Confirme e depois reinicie a VM no botão de start.
+
Snapshots são pontos de controle da máquina virtual. Para exemplificar, imagine o seguinte exemplo: você precisa instalar um programa instável, e ele pode corromper seu sistema.
+Para impedir isso, você cria um snapshot antes de instalar o programa. Se, durante a instalação do programa, ocorrer algum problema com seu sistema, você pode acessar o snapshot para voltar ao estado da máquina correspondente ao momento em que você criou o snapshot (antes de instalar o programa) e tomar as medidas necessárias para evitar a reincidência do erro.
+Para criar os snapshots, siga os passos abaixo:
+Concluir
para finalizar a criação do snapshotPara acessar os snapshots criados, siga os passos abaixo:
+Sim
para confirmar e retornar ao snapshot selecionadoÉ possível utilizar as portas físicas da sua máquina em uma máquina virtual. Exemplificando, posso conectar uma Raspberry Pi no meu sistema físico e utilizá-lo na máquina virtual com o Virt Manager.
+Para isso, siga os passos a seguir:
+Máquina Virtual
Redirecionar dispositivo USB
e selecione o dispositivo inseridoO NAO Flasher é uma ferramenta que permite a realização de updates no sistema do NAO v4 e do NAO v6, além do reset de fábrica e outras possibilidades.
+++Recomendação: usar no Linux Ubuntu 16.04 (Xenial Xerus).
+
Acesse o site da Aldebaran Robotics.
+Desça até o menu "NAO Flasher", e clique nele.
+Na aba "LINUX", clique no botão NAO Flasher 2.1.0 - Setup
.
O NAO Flasher baixado no site da Aldebaran Robotics vem em formato de binários, ou seja, não é necessária uma instalação usando um setup. Em outras palavras, basta executar o executável do NAO Flasher, através dos seguintes passos:
+Vá até a pasta onde o arquivo foi baixado.
+Clique sobre o arquivo tar.gz com o botão direito e selecione Extrair aqui
.
Abra a pasta instalada, e dentro dela acesse a pasta bin
, que deve conter um arquivo "Flasher".
Clique sobre o arquivo "Flasher" com o botão direito e selecione Propriedades
. Na aba Permissões
, marque a caixa Permitir execução do arquivo como um programa
.
Para executar o arquivo, clique com o botão direito na pasta bin
e selecione Abrir no terminal
. Em seguida, digite o seguinte código:
sudo ./flasher
+
++ +Caso abra a interface do NAO Flasher, a instalação foi concluída com sucesso.
+
Este é um guia de apresentação de conceitos-chave do framework NAOqi, conhecimento necessário para o início na programação dos robôs da Aldebaran Robotics.
+NAOqi: principal software usado no robô para controlá-lo.
+NAOqi Framework: é um framework que funciona como um broker (intermediário). Isso significa que ele interliga diversos módulos. Suponha que você precise programar uma ação específica fora das ações comuns de fábrica do robô. Para isso, o NAOqi utiliza um sistema que resgata os módulos disponíveis (inclusive módulos criados por você, que contenha as funções específicas que você precisa) e os disponibiliza em sua aplicação.
+Multiplataforma: disponível no Windows, Linux e MacOS
+Linguagens aceitas:
+Métodos ou funções: conjunto de instruções a serem realizadas.
+Módulo: conjunto de métodos, funciona como uma classe.
+Biblioteca: conjunto de módulos.
+Proxy: ao criar um proxy de determinado módulo, é possível acessar os métodos desse módulo através do proxy. Funciona como um objeto de uma classe.
+NAOqi Broker: é um intermediador dos módulos. Por exemplo: o módulo A, em um de seus métodos, precisa de um método do módulo B. O broker "avisa" o módulo A da existência do módulo B, possibilitando o acesso desejado.
+Autoload.ini: arquivo localizado no SO do robô, responsável por carregar as bibliotecas quando o robô é iniciado.
+ +Módulos locais: Estão em um mesmo ambiente (processo), e portanto podem compartilhar variáveis e métodos com outros módulos locais. Além disso, apenas um broker é necessário para a conexão entre módulos locais, não precisando de internet para tal conexão. É bem mais rápido que a conexão remota entre módulos.
+Módulos remotos: módulos que utilizam seu broker para se comunicar com outro broker que possui outros módulos. Utilizam a internet para se comunicarem (um broker precisa saber a porta e o IP do outro broker para trocarem informações). Possui velocidade menor em comparação com módulos locais.
+Conexão entre módulos remotos: imagine dois módulos remotos, A e B. A conexão entre eles pode ser broker x broker ou proxy x broker (objeto de A acessa B mas B não acessa A).
+Conexão broker x broker: nesse tipo de conexão, A acessa B e B acessa A. Ou seja, trata-se de uma comunicação recíproca. Para conectar módulos dessa maneira, basta especificar o IP e a Port (usando –pip e –pport na inicialização do módulo). Então, pode-se criar o proxy (objeto do módulo) com AL::ALProxy proxy = AL::ALProxy(nome_módulo)
(em C++) para acessar os métodos desse módulo. Como o IP e a Port já foram especificados com –pip e –pport, não é necessário informar esses na criação do proxy.
Conexão proxy x broker: nesse tipo de conexão, A acessa B, mas B não tem acesso a A. Um módulo (classe) pode se comunicar com outro módulo através da instanciação de seu proxy (objeto). Suponha que o broker de A (que possui o módulo A) se conecta com o broker de B (que "avisa" sobre a existência de B). O proxy de A consegue utilizar os métodos de B através do broker de B, mas os módulos registrados nesse broker (B) NÃO possuem acesso ao módulo (A) que possui esse proxy. Sendo assim, trata-se de uma comunicação de acesso unilateral.
+Criar um nome, usar um IP e uma porta.
+Os passos estão exemplificados aqui:
+// Um broker precisa de um nome, um IP e uma porta para "escutar":
+const std::string nomeBroker = "mybroker";
+
+// IP do NAOqi
+const std::string pip = "127.0.0.1"; // local NAOqi
+
+// Porta do NAOqi
+int pport = 9559;
+
+// Crie o seu próprio broker
+boost::shared_ptr<AL::ALBroker> broker = AL::ALBroker::createBroker(nomeBroker, "0.0.0.0", 54000, pip, pport);
+AL::ALProxy proxy = AL::ALProxy(broker, <nome_do_modulo>);
+
Chamadas bloqueadoras e não bloqueadoras
+Para chamar um método de um módulo, o NAOqi possibilita dois protocolos de chamadas:
+Bloqueadoras: chamada normal de um método. Instancia-se o objeto da classe e o utiliza usando a estrutura: modulo.metodo()
. Esse funcionamento é exatamente igual às chamadas normais de um método de uma classe.
Não bloqueadoras: serve para chamar um método e, ao mesmo tempo, executar outras ações. Por exemplo: fazer o robô andar e falar ao mesmo tempo. Para isso, utiliza-se um “post object” de um proxy. Isso cria um processo que será executado paralelamente à outras atividades. Toda chamada que usa esse post object gera um TaskID, que pode ser usado para verificar se a tarefa está sendo ou já foi executada. Para criar uma chamada não bloqueadora, use a seguinte estrutura: modulo.post.metodo()
.
ALMemory
+Essa ferramenta é a memória do robô.
+Todos os módulos podem ler (resgatar informações) ou escrever (registrar/alterar informações) na memória do robô. O ALMemory é um array de ALValues (valores do módulo ALValues podem ser de todos os tipos tradicionais encontrados na programação).
+Para evitar problemas de acesso concorrente à memória (ações divergentes ao mesmo tempo no mesmo local da memória), eles utilizam critical sections de leitura/escrita para proteger o acesso, ou seja, os threads permitem a execução de apenas um processo por vez, enquanto os outros ficam suspensos até que o processo atual termine. Isso protege os dados.
+Para que fique mais claro:
+Suponha que existam dois métodos no mesmo ambiente, X e Y.
+//Código X:
+
+a = 5
+
//Código Y:
+
+a = 8
+
Se esses códigos forem executados ao mesmo tempo, a execução correta das ações posteriores pode ser prejudicada. Para evitar esse erro nas operações de leitura/escrita em memória, usa-se a critical section.
+ +Este é um guia de apresentação de conceitos-chave do framework NAOqi, conhecimento necessário para o início na programação dos robôs da Aldebaran Robotics.
+NAOqi: principal software usado no robô para controlá-lo.
+NAOqi Framework: é um framework que funciona como um broker (intermediário). Isso significa que ele interliga diversos módulos. Suponha que você precise programar uma ação específica fora das ações comuns de fábrica do robô. Para isso, o NAOqi utiliza um sistema que resgata os módulos disponíveis (inclusive módulos criados por você, que contenha as funções específicas que você precisa) e os disponibiliza em sua aplicação.
+Multiplataforma: disponível no Windows, Linux e MacOS
+Linguagens aceitas:
+Métodos ou funções: conjunto de instruções a serem realizadas.
+Módulo: conjunto de métodos, funciona como uma classe.
+Biblioteca: conjunto de módulos.
+Proxy: ao criar um proxy de determinado módulo, é possível acessar os métodos desse módulo através do proxy. Funciona como um objeto de uma classe.
+NAOqi Broker: é um intermediador dos módulos. Por exemplo: o módulo A, em um de seus métodos, precisa de um método do módulo B. O broker "avisa" o módulo A da existência do módulo B, possibilitando o acesso desejado.
+Autoload.ini: arquivo localizado no SO do robô, responsável por carregar as bibliotecas quando o robô é iniciado.
+ +Módulos locais: Estão em um mesmo ambiente (processo), e portanto podem compartilhar variáveis e métodos com outros módulos locais. Além disso, apenas um broker é necessário para a conexão entre módulos locais, não precisando de internet para tal conexão. É bem mais rápido que a conexão remota entre módulos.
+Módulos remotos: módulos que utilizam seu broker para se comunicar com outro broker que possui outros módulos. Utilizam a internet para se comunicarem (um broker precisa saber a porta e o IP do outro broker para trocarem informações). Possui velocidade menor em comparação com módulos locais.
+Conexão entre módulos remotos: imagine dois módulos remotos, A e B. A conexão entre eles pode ser broker x broker ou proxy x broker (objeto de A acessa B mas B não acessa A).
+Conexão broker x broker: nesse tipo de conexão, A acessa B e B acessa A. Ou seja, trata-se de uma comunicação recíproca. Para conectar módulos dessa maneira, basta especificar o IP e a Port (usando –pip e –pport na inicialização do módulo). Então, pode-se criar o proxy (objeto do módulo) com AL::ALProxy proxy = AL::ALProxy(nome_módulo)
(em C++) para acessar os métodos desse módulo. Como o IP e a Port já foram especificados com –pip e –pport, não é necessário informar esses na criação do proxy.
Conexão proxy x broker: nesse tipo de conexão, A acessa B, mas B não tem acesso a A. Um módulo (classe) pode se comunicar com outro módulo através da instanciação de seu proxy (objeto). Suponha que o broker de A (que possui o módulo A) se conecta com o broker de B (que "avisa" sobre a existência de B). O proxy de A consegue utilizar os métodos de B através do broker de B, mas os módulos registrados nesse broker (B) NÃO possuem acesso ao módulo (A) que possui esse proxy. Sendo assim, trata-se de uma comunicação de acesso unilateral.
+Criar um nome, usar um IP e uma porta.
+Os passos estão exemplificados aqui:
+// Um broker precisa de um nome, um IP e uma porta para "escutar":
+const std::string nomeBroker = "mybroker";
+
+// IP do NAOqi
+const std::string pip = "127.0.0.1"; // local NAOqi
+
+// Porta do NAOqi
+int pport = 9559;
+
+// Crie o seu próprio broker
+boost::shared_ptr<AL::ALBroker> broker = AL::ALBroker::createBroker(nomeBroker, "0.0.0.0", 54000, pip, pport);
+AL::ALProxy proxy = AL::ALProxy(broker, <nome_do_modulo>);
+
Chamadas bloqueadoras e não bloqueadoras
+Para chamar um método de um módulo, o NAOqi possibilita dois protocolos de chamadas:
+Bloqueadoras: chamada normal de um método. Instancia-se o objeto da classe e o utiliza usando a estrutura: modulo.metodo()
. Esse funcionamento é exatamente igual às chamadas normais de um método de uma classe.
Não bloqueadoras: serve para chamar um método e, ao mesmo tempo, executar outras ações. Por exemplo: fazer o robô andar e falar ao mesmo tempo. Para isso, utiliza-se um “post object” de um proxy. Isso cria um processo que será executado paralelamente à outras atividades. Toda chamada que usa esse post object gera um TaskID, que pode ser usado para verificar se a tarefa está sendo ou já foi executada. Para criar uma chamada não bloqueadora, use a seguinte estrutura: modulo.post.metodo()
.
ALMemory
+Essa ferramenta é a memória do robô.
+Todos os módulos podem ler (resgatar informações) ou escrever (registrar/alterar informações) na memória do robô. O ALMemory é um array de ALValues (valores do módulo ALValues podem ser de todos os tipos tradicionais encontrados na programação).
+Para evitar problemas de acesso concorrente à memória (ações divergentes ao mesmo tempo no mesmo local da memória), eles utilizam critical sections de leitura/escrita para proteger o acesso, ou seja, os threads permitem a execução de apenas um processo por vez, enquanto os outros ficam suspensos até que o processo atual termine. Isso protege os dados.
+Para que fique mais claro:
+Suponha que existam dois métodos no mesmo ambiente, X e Y.
+//Código X:
+
+a = 5
+
//Código Y:
+
+a = 8
+
Se esses códigos forem executados ao mesmo tempo, a execução correta das ações posteriores pode ser prejudicada. Para evitar esse erro nas operações de leitura/escrita em memória, usa-se a critical section.
+ +Guia de instalação do ROS1 em uma máquina nativa ou máquina virtual no Ubuntu 20.04
+Conforme instruções disponibilizadas na ROS wiki.
+Os seguintes passos devem ser realizados no terminal da VM criada.
+sudo apt update
+sudo add-apt-repository restricted
+sudo add-apt-repository universe
+sudo add-apt-repository multiverse
+sudo apt update
+
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
+
sudo apt install curl
+curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
+
sudo apt update
+
++Instalação completa (tudos os recursos da versão padrão + softwares de visualização 2D/3D e percepção 2D/3D):
+
sudo apt install ros-noetic-desktop-full
+
++Instalação padrão (tudo da versão simples + algumas ferramentas como rqt e rviz):
+
sudo apt install ros-noetic-desktop
+
++Instalação simples (pacotes do ROS, bibliotecas de compilação e comunicação. Sem GUI.)
+
sudo apt install ros-noetic-ros-base
+
sudo apt install ros-noetic-NOME_DO_PACOTE
+
apt search ros-noetic
+
Você deverá 'fontear' esse script em qualquer terminal bash no qual você use o ROS:
+source /opt/ros/noetic/setup.bash
+
Pode ser conveniente fazer isso automaticamente toda vez que iniciar um novo shell para usar o ROS:
+echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
+source ~/.bashrc
+
echo "source /opt/ros/noetic/setup.zsh" >> ~/.zshrc
+source ~/.zshrc
+
sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential
+
sudo rosdep init
+rosdep update
+
dpkg -s ros-noetic-ros
+
Com este tutorial, o ROS 1 - Noetic estará instalado em sua máquina.
+ +O Robot Settings 2.8.6 é um programa usado para configurar e gerenciar robôs NAO v6 da Softbank Robotics.
+Entretanto, até o momento da criação desse tutorial, o Robot Settings 2.8.6 é compatível (em distribuições Ubuntu) apenas na versão 16.04 (Xenial Xerus).
+Os seguintes passos devem ser realizados dentro da VM com Ubuntu 16.04 ou em um sistema com Ubuntu 16.04 nativo.
+OK
Pressione CTRL+ALT+T
para abrir o terminal. Execute os comandos abaixo:
cd ~/Downloads
+chmod +x robot-settings-2.8.6.23-linux64-setup.run
+sudo ./robot-settings-2.8.6.23-linux64-setup.run
+
Prosseguindo com a instalação:
+Next
até que apareça o botão Install
Install
, aguarde a instalação e clique em Finish
Com a realização dos passos acima, o Robot Settings estará instalado e operante, podendo ser encontrado no menu de navegação do Ubuntu ou na área de trabalho.
+++ +Cabe ressaltar que, como o Robot Settings não é compatível com o Ubuntu 22.04, deve-se sempre acessá-lo através da máquina virtual (com Ubuntu 16.04) gerenciada pelo Virt Manager, ou por uma máquina com Ubuntu 16.04 nativo para garantir a compatibilidade do sistema.
+
{"use strict";/*!
+ * escape-html
+ * Copyright(c) 2012-2013 TJ Holowaychuk
+ * Copyright(c) 2015 Andreas Lubbe
+ * Copyright(c) 2015 Tiancheng "Timothy" Gu
+ * MIT Licensed
+ */var Ha=/["'&<>]/;Nn.exports=$a;function $a(e){var t=""+e,r=Ha.exec(t);if(!r)return t;var o,n="",i=0,s=0;for(i=r.index;i