ROS Services: Uma alternativa ao mecanismo de pub-sub do ROS

Olá caro leitor, nesse texto continuaremos a explorar mais algumas capacidades do ROS, o sistema operacional para robôs. Neste artigo vamos falar um pouco de um sistema alternativo ao método publish-subscribe de comunicação do ROS, os ROS Services.

 

Modelo cliente - servidor no ROS? Precisamos mesmo?

 

Um exemplo? Um manipulador holonômico de 7 graus de liberdade precisa movimentar seu end-effector (junta que realiza o trabalho de fato) de um ponto A para um ponto B obedecendo uma série de limitações impostas pelo ambiente. Porém, antes de mover para esse ponto, o ROS node que controla esse robô precisa fazer uma série de cálculos e planejar a trajetória do manipulador, gerando uma lista de configurações para cada junta até que o ponto B seja alcançado ou reportando um aviso de que essa trajetória não pode ser planejada. Observando a figura temos um exemplo desse tipo de manipulador PUMA 560 planejando a trajetória:

ROS Services: Manipulador PUMA 560 e um exemplo de trajetória
Figura 1: Manipulador PUMA 560 e um exemplo de trajetória

 

Agora considerem que temos uma aplicação contendo três ROS nodes, um para tarefa (execution), outro para planejar o movimento (planner) e um de controle (control). Pensando no ROS node execution, uma vez em que conhecemos o ponto A e o ponto B, esse node não pode simplesmente pedir ao control para executar o movimento das juntas, primeiro ele deve perguntar ao planner se a trajetória é legal e como deve realizá-la, não podendo tomar qualquer ação até que o planner responda.

Seria possível estabelecer esse fluxo utilizando o sistema pub-sub que já conhecemos, porém teríamos que lidar com o trabalho extra de sincronizar o ROS node execution com a resposta do planner antes de comunicar com o control. É nesse momento que os ROS services são indicados, estes módulos permitem que um determinado ROS node faça uma requisição (cliente) a um serviço e suspenda sua execução até que aquele (servidor) responda com o resultado da operação.

 

Agora explicando como trabalhar com o ROS service:

 

Os ROS services são oferecidos por todas client libraries do ROS, seja em C++ ou Python, não sendo necessário qualquer instalação extra caso o ROS já esteja instalado no seu computador ou no seu computador embedded (Raspberry por exemplo…).

 

De forma similar as ROS messages, um ROS service precisa de um arquivo descrevendo o servidor bem como quais os tipos de dados que irão trafegar na requisição e qual tipo de dado é devolvido na resposta. Esses arquivos são colocados na pasta srv, usando a extensão .srv, abaixo um exemplo de um arquivo desse tipo que utilizei para criar um serviço capaz de calcular a cinemática inversa de um manipulador KUKA KR210:

 

O arquivo descritor é dividido em duas seções, antes do marcador ---, onde o tipo de dado da requisição é colocado, no caso do arquivo acima o servidor de cinemática inversa recebe uma lista de posições e devolve uma outra de lista de posições. Percebam ainda que é possível utilizar tipos complexos de dados como o geometry e trajectory messages que são construídos a partir do sistema primitivo de mensagens do ROS.

 

Com o descritor de serviço definido, basta agora utilizar o módulo de serviços e escrever seu ROS node como de costume. A partir do arquivo descritor um módulo em C++ ou Python vai ser gerado de forma que o usuário consiga incluir e manipular o tipo de dado no código do seu ROS node.

 

E vamos ao exemplo no ROS:

 

Vamos criar aqui dois ROS nodes, sendo um cliente que faz requisições e só publica o resultado da requisição após receber a resposta do ROS node responsável pelo serviço, ao mesmo tempo teremos o ROS servidor publicando no mesmo tópico que está processando a requisição. O usuário irá perceber que as mensagens estarão sempre sincronizadas já que o ROS node cliente também estará sincronizado com o ROS node servidor.

 

Para começarmos esse exemplo, vá para a sua worskpace do ROS e crie um ROS package, com o nome de sua preferência. Não sabe do que estou falando? Então você precisa visitar o tópico de bases do ROS começando por este artigo, e ao terminar volte aqui para continuarmos.

 

Uma vez criada, crie a pasta srv dentro do diretório topo do seu package, dentro dela crie o arquivo test_service.srv e edite-o da seguinte maneira:

 

 

Com o descritor criado, agora precisamos avisar ao build system do ROS que esse serviço precisa ser gerado, para isso primeiro vamos alterar o conhecido arquivo CMakeLists.txt no diretório raiz do seu package e devemos adicionar os pacotes para geração de mensagens:

 

 

E incluir o serviço que desejamos gerar:

 

Iremos voltar logo mais nesse arquivo quando adicionarmos o código dos nossos nodes, agora vamos ao arquivo package.xml que também está na raiz do seu package, adicione as seguintes linhas:

 

Basicamente estamos adicionando no nosso package a obrigatoriedade de considerar as dependências de geração de mensagem, com isso sendo possível chamar o comando para gerar os serviços durante o build.

 

Vamos testar se o serviço está sendo gerado, para isso, no diretório raiz da workspace (atenção, não é do package, são dois níveis acima) e no terminal execute o build e verifique se o serviço foi gerado, você deve obter o conteúdo do arquivo .srv:

 

Testando o serviço adicionado
Figura 2: Testando o serviço adicionado

 

Vamos ao ROS nodes agora:

 

Agora que temos nosso serviço pronto, vá para o diretório do seu package e na pasta src, adicione dois arquivos, server_node.cpp e client_node.cpp. Comecemos pelo client_node, adicione o código abaixo:

 

E agora em server_node, cole o código abaixo:

 

Agora volte ao arquivo CMakeLists.txt e adicione as linhas para que os arquivos sejam compilados e os executáveis gerados:

 

O comando add_dependecies informa ao build systems para gerar os arquivos de código fonte relativos ao serviço que configuramos no nosso package. E agora estamos prontos para fazer o build no nosso exemplo de serviço ROS. Invoque o comando catkin_make para fazer o build do seu package.

 

Testando o serviço gerado com o ROS:

 

Se você leu até aqui antes de implementar qualquer coisa e quer apenas testar, tenho uma notícia para você, o package de teste completo encontra-se no meu github e você pode clonar ele direto na sua workspace, para isso basta checar esse link aqui. Ou se fez todos os passos anteriores e conseguiu compilar seu package, então vamos agora ver as coisas funcionando, primeiramente você vai precisar abrir três janelas de terminal que chamarei respectivamente de core, server e client.

 

De preferência em todas elas vá para o diretório raiz da sua catkin workspace, primeiramente vamos subir o ROS no seu PC ou dispositivo embarcado, para isso no terminal core faça como no exemplo abaixo invocando o roscore:

Lançando o roscore
Figura 3: Lançando o roscore

 

Na janela server dispare a execução do ROS node servidor, como no exemplo:

Disparando o server
Figura 4: Disparando o server.

 

O servidor irá aguardar a comunicação do ROS cliente, que pode ser executado como no exemplo abaixo, para isso vá para a janela client:

 

Disparando o ROS node cliente
Figura 5: Disparando o ROS node cliente

 

Veja que de imediato o cliente vai fazer requisição ao server que vai dar uma resposta a ele, além disso voltando na janela server poderemos ver que o fluxo de comunicação também é mostrado:

 

Fluxo de comunicação no ROS node servidor
Figura 6: Fluxo de comunicação no ROS node servidor

 

Ele estava aguardando conexão do cliente, e agora encontra-se publicando a atividade entre as requisições com isso efetivamente temos um servidor pronto para ser incrementado com sua aplicação de robótica que precisa do modelo-cliente servidor.

 

Conclusão:

 

O objetivo desse artigo era explorar mais uma faceta do sistema de comunicação do ROS, os serviços, capazes de implementar um modelo cliente servidor de comunicação entre os ROS nodes, exemplificamos onde esse tipo de modelo pode ser útil e apresentamos ao leitor um exemplo funcional seguido dos passos para adicionar um serviço em um ROS package. Com esse conhecimento sobre ROS adquirido nos artigos aqui publicados o leitor já vai obter bagagem suficiente para os próximos textos, fiquem ligados pois nas próximas publicações vamos testar vários pacotes ROS interessantes que podem dar aquele incremento no seu próximo projeto de Robô, então fiquem ligados!

 

Referencias

 

1 - CACACE, Jonathan - Mastering ROS for Robotics Programming - 2nd Ed.

2 - http://wiki.ros.org/ROS/Tutorials/CreatingMsgAndSrv

3 - https://github.com/uLipe/test_package

NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Felipe Neves
Desenvolvedor de sistemas embarcados apaixonado pelo que faz, divide seu tempo entre trabalhar no Venturus desenvolvendo firmware de tudo quanto é coisa, na Aeolus Robotics se envolvendo com o que há de mais legal em robótica e na Overlay Tech desenvolvendo algumas coisas bem legais para o campo de motion control. Possui mestrado em engenharia elétrica pela Poli-USP e possui interesse em tópicos como: Software embarcado, sistemas de tempo real, controle, robótica móvel e manipuladores, Linux embedded e quase qualquer coisa por onde passe um elétron.

Deixe um comentário

avatar
 
  Notificações  
Notificar