o Sistema operacional robótico (ROS) não é realmente um sistema operacional, mas uma estrutura e um conjunto de ferramentas que fornecem a funcionalidade de um sistema operacional em um grupo heterogêneo de computadores. Sua utilidade não se limita a robôs, mas a maioria das ferramentas fornecidas concentra-se no trabalho com hardware periférico.
ROS Está dividido em mais de 2.000 pacotes, cada pacote possui uma funcionalidade especializada. A quantidade de ferramentas conectadas ao framework é provavelmente seu maior poder.
O ROS fornece funcionalidade para abstração de hardware, drivers de dispositivo, comunicação entre processos em várias máquinas, ferramentas para teste e visualização e muito mais.
A principal característica do ROS é a forma como o software é executado e se comunica, pois permite que você projete software complexo sem saber como determinado hardware funciona. O ROS fornece uma maneira de conectar uma rede de backbone de processos (nós). Os nós podem ser executados em vários dispositivos e se conectar a esse hub de várias maneiras.
As principais maneiras de criar uma rede são fornecer os serviços necessários ou definir conexões de anunciantes ou assinantes com outros nós. Ambos os métodos se comunicam por meio de tipos específicos de mensagens. Alguns tipos são fornecidos por pacotes principais, mas os tipos de mensagens podem ser definidos por pacotes individuais.
Os desenvolvedores podem montar um sistema complexo conectando soluções existentes para pequenos problemas. A forma como o sistema é implementado nos permite:
Substitua componentes com interfaces semelhantes em tempo real, eliminando a necessidade de interromper o sistema para várias alterações.
Multiplexar a saída de vários componentes em uma entrada de outro componente, permitindo a solução paralela de vários problemas.
Conecte componentes feitos em várias linguagens de programação simplesmente implementando os conectores apropriados para o sistema de mensagens, tornando o desenvolvimento de software mais fácil conectando módulos existentes de vários desenvolvedores.
Crie nós em uma rede de dispositivos sem se preocupar com onde um código é executado e implemente sistemas de comunicação entre processos (IPC) e chamada de procedimento remoto (RPC).
Conecte-se diretamente a streams sob demanda de hardware remoto sem escrever código extra, usando os dois pontos anteriores.
Pretendemos demonstrar o quão útil é, desenvolvendo iterativamente uma solução simples. Existem várias vantagens importantes em comparação com outras abordagens. O ROS tem suporte multiplataforma e permite conexões entre processos de vários dispositivos, por meio de conexões de pares que são tratadas em segundo plano. O design permite suporte para qualquer linguagem ao determinar as classes de comunicação C ++, ou desenvolver classes manualmente para a interface de linguagem.
ROS é feito por sua própria comunidade. Depois de vários anos, resultou em um grande número de pacotes reutilizáveis que são fáceis de integrar graças à arquitetura do sistema.
Abordagens alternativas como MRPT , CARMEN , LCM , Jogador , Microsoft RDS e outros fornecem alguns desses recursos, mas não todos. Na maioria das vezes, as falhas de design são limitações de suporte de idioma, comunicação deficiente entre processos ou falta de suporte para vários dispositivos, o que é indiscutivelmente o problema mais difícil de resolver.
Como nosso foco é o framework e não os algoritmos como tal, para problemas particulares, o problema fornecido será muito simples. Nosso objetivo é construir um software para um computador que faça parte do processo e nos permita controlar e monitorar remotamente um robô, conectado a nós via Wi-Fi, usando um gamepad em nosso computador e uma transmissão da câmera montada no robô .
definir o poder de barganha dos fornecedores
Em primeiro lugar, conectaremos um programa simples a uma simulação simples, apenas para demonstrar os princípios básicos do ROS. Vamos vincular um gamepad a um computador e tentar projetar um bom esquema de controle para passar a entrada do gamepad para controlar os sinais de um robô.
As principais linguagens para escrever código ROS são C ++ e Python, C ++ é o preferido para desempenho inferior. Explicaremos nossos exemplos em Pitão porque tem menos qualificador no código e não há necessidade de fazer uma construção específica.
As versões ROS são referidas pelo nome. Até o momento, o lançamento mais recente é Jade Turtle , e a versão LTS é Iglu índigo . Ir da versão é preferível e a compatibilidade com versões anteriores não é garantida no ROS, então todos os exemplos serão escritos para Índigo .
O ROS está disponível em várias plataformas * NIX. A versão oficialmente suportada está no Ubuntu. As versões OS X, Arch Linux, Debian, Raspbian e Android são suportadas pela comunidade.
Veremos o processo de instalação do Ubuntu 14.04 no desktop. Processos para todas as versões e plataformas suportadas estão disponíveis no página oficial . Também estão disponíveis máquinas virtuais com ROS já instalado.
A instalação depende da plataforma (e a maioria das plataformas tem pacotes agrupados), mas as configurações do espaço de trabalho são as mesmas para todas as plataformas. .
ROS fornece seus próprios repositórios. O primeiro passo é adicioná-los.
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-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 0xB01FA116 sudo apt-get update
Depois disso, você terá todos os pacotes hospedados para todas as versões de ROS disponíveis para sua versão do Ubuntu. Por exemplo, o Ubuntu 14.04 oferece suporte a indigo
e jade
.
Instalar os pacotes básicos no desktop tem uma das três opções:
sudo apt-get install ros-indigo-ros-base
para instalação mínima
sudo apt-get install ros-indigo-desktop
ter a ferramenta GUI básica adicional
sudo apt-get install ros-indigo-desktop-full
ter todos os recursos oficiais, incluindo vários simuladores e bibliotecas para navegação e percepção.
Para uma melhor experiência de trabalho, a opção completa é recomendada. Para instalação em dispositivos que serão usados apenas para executar nós, a versão ase é suficiente. Mas não importa qual opção você escolha, você pode instalar qualquer pacote que precisar, chamado package_name
ao executar:
sudo apt-get install ros-indigo-
Os sublinhados são substituídos por hífens no nome final, então stage_ros
estará no pacote como ros-indigo-stage-ros
.
A próxima etapa é iniciar rosdep
. Os pacotes no ROS podem declarar de quais componentes eles dependem. rosdep
permite que você compile esses pacotes sem depender muito de manipulação manual. Para iniciá-lo, ligue:
sudo rosdep init rosdep update
O ROS possui muitas variáveis ambientais utilizadas por suas ferramentas. Com a instalação padrão, o script bash para iniciá-los, ele está localizado em /opt/ros/indigo/setup.bash
. As variáveis precisam ser iniciadas em cada sessão de bash , então a melhor solução é adicioná-los a ~/.bashrc
.
echo 'source /opt/ros/indigo/setup.bash' >> ~/.bashrc source ~/.bashrc
Alguns pacotes instalam dependências externas por meio de rosinstall
, que está disponível como um pacote e instalado por meio de sudo apt-get install python-rosinstall
.
Este é o fim da instalação do Ubuntu. A seguir, uma breve introdução à configuração do espaço de trabalho.
Desde a Galápagos bacanas , Os espaços de trabalho ROS foram gerenciados por meio de catkin
. Precisamos definir um diretório para todos os pacotes que hospedamos. Dentro do diretório, criamos uma pasta src
e chamamos catkin_init_workspace
de dentro. Isso criará vários links simbólicos na versão fonte atual do ROS. A próxima etapa é incluir também essa área de trabalho nas variáveis de ambiente.
Para realizar todas essas configurações de espaço de trabalho, escolha um diretório vazio e execute os seguintes comandos:
mkdir src cd src catkin_init_workspace cd .. catkin_make echo 'source $(pwd)/devel/setup.bash' >> ~/.bashrc source ~/.bashrc
Você acabou de criar uma área de trabalho onde pode criar seus próprios pacotes ROS.
Criar qualquer código é um grande salto. Primeiro, vamos nos familiarizar com alguns dos sistemas que funcionam nos bastidores. Nossa primeira etapa será executar a GUI básica e ver quais mensagens ela gera.
Para executar qualquer coisa no ROS, você precisa iniciar um processo principal. É tão fácil quanto abrir uma nova janela de terminal e digitar:
roscore
Em toda a rede do dispositivo conectado, roscore
ele precisa ser executado apenas uma vez, no dispositivo que hospedará o hub central para enviar a comunicação.
A principal função de roscore
isto é, dizer aos nós aos quais outros nós devem se conectar, e de que maneira (seja por meio de porta de rede ou memória compartilhada). O objetivo é permitir que os nós se preocupem apenas com os dados que desejam saber, em vez de a qual nó desejam se conectar, minimizando o tempo ou a largura de banda necessários para realizar todas as comunicações.
Depois de executar roscore
, podemos lançar a ferramenta GUI principal para ROS: rqt
. O que vemos é muito decepcionante - uma janela vazia. rqt
Ele hospeda uma grande variedade de plug-ins que podem ser configurados em qualquer configuração visual e qualquer número de visualizações predefinidas.
Para começar, executamos o plugin Robô de direção , escolhendo-o em Plugins > Robot Tools > Robot Steering
. O que obtemos são dois controles deslizantes, que representam o movimento linear e rotacional que queremos que nosso robô tenha. No topo do plugin, vemos uma caixa de texto com /cmd_vel
nela. Podemos dar outro nome. Representa o nome do tópico ao qual a publicação é direcionada. As ferramentas de terminal são o melhor lugar para ver o que acontece em segundo plano.
O ROS possui várias ferramentas poderosas para inspecionar o que está acontecendo no sistema. A primeira ferramenta que vamos apresentar é rostopic
, que nos permite inspecionar tópicos que os nós podem assinar e publicar. Executar rostopic list
dar para:
estado da indústria da música
/cmd_vel /rosout /rosout_agg
Os dois últimos tópicos estão sempre em execução e relacionados aos principais sistemas ROS. O tópico /cmd_vel
está sendo publicado por nossos endereços. Renomear o tópico nos endereços irá renomeá-lo aqui também. Agora, estamos interessados no que acontece dentro do assunto. Executar rostopic echo /cmd_vel
não nos mostrará nada (a menos que você toque com os controles deslizantes). O processo continua até que o cancelemos. Agora vamos mover o controle deslizante vertical a 20 m / s. Olhando para o eco, podemos ver o seguinte repetido continuamente:
linear: x: 0.2 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 0.0
Com que frequência esta mensagem é spam? rostopic hz /cmd_vel
diz a uma taxa média de 10 Hz. Bem, quantas músicas como esta posso executar na minha conexão Wi-Fi lenta? rostopic bw /cmd_vel
detecta uma média de 480 B / s.
Tudo bem, mas estamos falando sobre tipos de mensagens. Esses dados são bons para um ser humano, mas um aplicativo precisará dos dados brutos e precisará saber o tipo de mensagem para interpretar os dados. O tipo de mensagem pode ser interpretado com rostopic type /cmd_vel
, informando-nos que é um geometry_msgs/Twist
. Todas as ferramentas de terminal ROS chamadas sem nenhum argumento retornam uma mensagem de ajuda padrão.
O ROS Wiki é bom para fazer uma pesquisa na web para esse resultado de string, em uma explicação Wiki do que ele contém e como está estruturado. Mas não precisamos confiar nele. rosmsg
é a ferramenta geral para tipos de mensagens. Executar rosmsg show geometry_msgs/Twist
Retorna:
geometry_msgs/Vector3 linear float64 x float64 y float64 z geometry_msgs/Vector3 angular float64 x float64 y float64 z
A mensagem consiste em dois vetores 3D que representam a velocidade linear e angular no espaço 3D.
Se você quiser saber a quais tópicos um nó se conecta, rosnode info
Isso nos dará dados detalhados sobre o nó. As ferramentas rostopic
, rosmsg
e rosnode
são as principais ferramentas para inspecionar a funcionalidade ROS não polida. O ROS tem muito mais GUI e ferramentas de terminal, mas essas estão fora do escopo desta introdução.
As principais ferramentas para executar o nó ROS são rusrun
e roslaunch
. rosrun
você pode executar nós via rosrun
e roslaunch
ele executa nós com base em arquivos de lançamento, com os quais nos tornaremos pouco familiarizados, pois são o elemento mais complexo da automação ROS.
Podemos desligar tudo o que executamos para começar a trabalhar em nosso primeiro código. Para referência futura, será óbvio que a execução de qualquer coisa relacionada ao ROS requer uma instância ativa de roscore
. Muitos dos problemas que você encontrar podem ser resolvidos fechando a janela do terminal executando roscore
e abra um novo para reiniciá-lo. Isso atualiza todas as dependências que precisaram ser recarregadas, tanto em bash
e em roscore
.
Nosso primeiro objetivo é imitar a funcionalidade de Robot Steering
criando um nó que publica dados de geometry_msgs/Twist
a /cmd_vel
com base em uma entrada de gamepad. Nossa primeira parada é o pacote joy
.
joy
O pacote joy
fornece drivers ROS genéricos para joystick e gamepads. Ele não está incluído na instalação padrão, portanto, precisa ser instalado por meio de:
sudo apt-get install ros-indigo-joy
Após a instalação, podemos executar rosrun joy joy_node
. Isso nos conectará ao joystick ou gamepad, por padrão. Executar rostopic list
nos mostra que temos um tópico chamado /joy
. Ouça via rostopic echo
Mostra-nos mensagens no seguinte formato (note que tem de interagir com o gamepad ou joystick para que as mensagens sejam publicadas).
header: seq: 4156 stamp: secs: 1450707466 nsecs: 204517084 frame_id: '' axes: [0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0] buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Você pode ignorar os cabeçalhos por enquanto. Além disso, temos axes
e buttons
, que explicam muito bem o que representam. Movendo o machados e empurre o botões no controlador, isso resultará na alteração desses números. Usando nossas ferramentas, podemos determinar que o tipo de mensagem é sensor_msgs/Joy
e o formato é:
std_msgs/Header header uint32 seq time stamp string frame_id float32[] axes int32[] buttons
A primeira etapa para escrever código é criar um pacote. Dentro da pasta src
no espaço de trabalho, execute:
catkin_create_pkg toptal_tutorial rospy joy geometry_msgs sensor_msgs
Aqui declaramos o nome do pacote que estamos criando, seguido pelos pacotes dos quais planejamos depender. Não se preocupe, as dependências podem ser atualizadas manualmente mais tarde.
Agora temos uma pasta toptal_tutorial
. Dentro da pasta, crie uma pasta chamada scripts
que conterá todos os nossos scripts Python.
Vamos criar um arquivo chamado teleop.py
, e dentro dele teremos:
#!/usr/bin/env python import rospy from sensor_msgs.msg import Joy def joy_callback(data): print data def main(): rospy.init_node('teleop') rospy.Subscriber('joy', Joy, joy_callback) while not rospy.is_shutdown(): pass if __name__ == '__main__': main()
Também precisamos definir chmod +x teleop.py
portanto, o script é executável. Executar rosrun joy joy_node
em um terminal e rosrun toptal_tutorial teleop.py
em outro, isso resultará na saída do terminal teleop.py
sendo preenchida com mensagens Alegria .
Vamos examinar o que o código faz.
Primeiro, nós importamos rosado , que hospeda a biblioteca para interagir com a estrutura ROS. Cada pacote que define mensagens possui um subpacote msg
com definições de mensagem. Estamos importando Joy
para lidar com a entrada. Não há necessidade de importar tipos de mensagem incorporados (como Header
de std_msgs.msg
que está na mensagem Joy
), a menos que desejemos mencioná-los especificamente.
Nosso primeiro passo é inicializar um nó com um nome específico (neste caso, chamamos de 'teleop'). Depois disso, criamos um assinante que se inscreve no tipo de tópico 'alegria' sensor_msgs.msg.Joy
e que lida com cada mensagem chamando a função joy_callback
. Os callbacks recebem um parâmetro, os dados da mensagem. Acessar membros de dados é simples. Se quiséssemos imprimir o estado do primeiro eixo , se nos lembrarmos do tipo de mensagem, chamaríamos print data.axes[0]
e seria um float. O nó no final dos nós, até que o ROS desapareça.
Nosso próximo passo seria gerenciar nossos dados de alguma forma. Devemos criar uma mensagem Torção que muda, dependendo da entrada e então publicaríamos no tópico cmd_vel
.
trello vs asana vs jira
#!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist # new from functools import partial # new def joy_callback(pub, data): # modified cmd_vel = Twist() # new cmd_vel.linear.x = data.axes[1] # new cmd_vel.angular.z = data.axes[0] # new pub.publish(cmd_vel) # new def main(): rospy.init_node('teleop') pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) # new rospy.Subscriber('joy', Joy, partial(joy_callback, pub)) # modified while not rospy.is_shutdown(): pass if __name__ == '__main__': main()
Primeiro, adicionamos a mensagem Twist
e adicionamos suporte para argumentos funcionais com ligações via functools.partial
. Criamos um anunciante, pub
, que publica em cmd_vel
um tipo de mensagem Twist
. Vinculamos esse anunciante ao retorno de chamada e o fazemos postar uma mensagem Torção em cada entrada com as velocidades sendo representadas pelos dois primeiros machados . Este código faz o que se espera dele e podemos ver a saída resultante por meio de rostopic echo /cmd_vel
.
Ainda temos um problema. O tópico /joy
pode postar grandes velocidades. Se monitorarmos o rostopic hz /cmd_vel
e movemos o stick analógico em círculos, podemos ver muitas mensagens. Isso resultará não apenas em um grande número de comunicações, mas também nos processos que recebem essas mensagens para processar cada uma delas; Não há necessidade de postar tantos dados com tanta frequência e, na verdade, é melhor postar a uma taxa estável de 10 Hz. Podemos fazer isso com o código a seguir.
#!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist from functools import partial def joy_callback(cmd_vel, data): # modified cmd_vel.linear.x = data.axes[1] cmd_vel.angular.z = data.axes[0] # moved pub.publish(cmd_vel) to main loop def main(): rospy.init_node('teleop') cmd_vel = Twist() # new pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) rospy.Subscriber('joy', Joy, partial(joy_callback, cmd_vel)) # modified rate = rospy.Rate(10) # new while not rospy.is_shutdown(): pub.publish(cmd_vel) # new rate.sleep() # new if __name__ == '__main__': main()
Modificamos o callback para receber o objeto mutável Twist
e modifique-o dentro do loop. A função sleep
de rospy.Rate
mantém uma frequência de saída estável.
O código final resultará no tópico /cmd_vel
obter velocidades de comando de 10 Hz, imitando assim a saída do plugin Robô de direção rqt
Nosso primeiro objetivo é criar um ambiente em que possamos simular o cenário que queremos alcançar. O nó stageros
dentro da embalagem stage_ros
Isso nos permitirá executar um robô em um estágio 2D definido por uma imagem. Há toda uma síntese descrita no pacote stage_ros
para arquivos mundiais e como gerá-los. Isso é bastante simples, mas fora de alcance. Felizmente, o pacote vem com várias demos mundiais. Primeiro, vamos para o diretório de arquivos por execução:
roscd stage_ros cd world
Dentro da pasta existem vários arquivos. Vamos fazer um.
rosrun stage_ros stageros willow-erratic.world
Vários temas foram criados. O significado de cada um deles também é documentado com o pacote. O importante é que ele tenha cmd_vel
.
Dentro do estágio mostrado, há uma caixa azul, que representa o robô que você controla. Usando nosso código ou Robô de direção podemos controlar este robô. Tente!
Primeiro, criamos uma pasta launch
ou lanzamiento
dentro de nosso pacote e dentro dele, crie um arquivo chamado teleop.launch
. A estrutura final da pasta deve ser semelhante a esta:
toptal_tutorial/ ├── CMakeLists.txt ├── launch │ └── teleop.launch ├── package.xml ├── scripts │ └── teleop.py └── src
Dentro do arquivo teleop.launch
Vamos definir vários nós e suas interconexões.
robot_
O novo mundo consiste em 4 robôs e cada um de seus temas possui um prefixo chamado robot_0/cmd_vel
. Portanto, o robô número 0 tem um tema de velocidade de comando chamado robot_0
. É por isso que colocamos nosso controle dentro do namespace chamado roscore
e assim ajustaremos seus nomes à nova forma. Dessa forma, você pode pensar nos nomes dos tópicos como pastas em um sistema de arquivos.
qual princípio de organização perceptual é mostrado aqui
Você não precisa roscore
para executar arquivos de ativação. De certa forma, roscore
é apenas um caso especial de um arquivo de inicialização que não faz nada. Se um roslaunch toptal_tutorial teleop.launch
apenas o primeiro arquivo de inicialização executado executará um kernel, enquanto o resto se conectará a ele. Agora vamos executar o lançamento com:
/robot_/base_pose_ground_truth /robot_/base_scan_0 /robot_/base_scan_1 /robot_/camera_info_0 /robot_/camera_info_1 /robot_/cmd_vel /robot_/depth_0 /robot_/depth_1 /robot_/image_0 /robot_/image_1 /robot_/odom
Se tudo estiver em ordem resultará em um simulador com 4 robôs, onde cada um é controlado com o gamepad ou joystick. Este mundo tem muito mais conteúdo do que o anterior. Cada um dos quatro robôs tem o seguinte:
rqt
Substituímos por 0, 1, 2 ou 3. E com isso chegamos ao nosso último tópico.
rqt
Anteriormente, não nos aprofundamos em image_0
mas é a ferramenta perfeita para visualizar dados mais complexos. Você pode experimentar todos os temas, mas nos concentraremos nos temas image_1
, depth_0
, depth_1
e rqt
.
Em execução Plugins > Visualización > Vista Imagen
removemos todos os plug-ins abertos. Agora vamos abrir 4 visualizadores de imagens (robot_0
) e colocá-los em uma grade 2x2. Finalmente, no canto superior esquerdo de cada uma das visualizações, escolheremos um dos quatro temas estabelecidos para stage_ros/world
.
O que obtemos é uma visão estéreo de percepção profunda com câmeras de baixa resolução. Observe que poderíamos ter obtido este resultado sem nosso sistema de entrada. Se apenas executarmos isso (de dentro da pasta rosrun stage_ros stageros willow-four-erratics-multisensor.world
):
/robot_0/cmd_vel
E nós adicionamos o plugin Robô de direção com um tópico denominado export ROS_MASTER_URI=http://:11311/
Poderíamos ter obtido o mesmo resultado se os controles estivessem na tela.
Muitos hardwares oferecem suporte total a ROS, geralmente graças a terceiros. Muitas plataformas de robôs possuem drivers que geram esses tipos de mensagens e ROS possui nós que ativam a webcam e publicam um feed de imagens.
Enquanto o último resultado foi uma simulação do que queremos alcançar; o mesmo pode ser alcançado com as seguintes modificações:
rqt
quando você inicia no Bash, então o computador remoto irá olhar para aquele host e portagazebo
e / ou qualquer script para monitorar e controlar o robôNo final, apenas o ambiente de variável apropriado deve ser exportado no dispositivo remoto e todo o resto é feito por ele mesmo. Executar o ROS em um cluster de computador exige apenas uma etapa para ficar pronto em cada máquina.
Mostramos como, com cada código, por menor que seja, você pode ter um sistema complexo de variáveis que pode manipular da maneira que quiser. O sistema simples de editor / assinante permite o rápido desenvolvimento de software que processa dados em um cluster de computadores, enquanto deixa você paz de espírito para que você não se preocupe com a implementação de certos elementos.
Enquanto usamos um simulador simples, outros simuladores mais complexos como
|_+_|(que está incluído na versão desktop completa) permitem que você crie Mundos 3D com sensores físicos complexos E dá a você uma experiência dos resultados finais e do produto antes de ser desenvolvido.
Esta introdução foi um tanto básica, mas esperamos que você se interesse mais em trabalhar com esta estrutura versátil.