## page was copied from ROS/Tutorials/WritingServiceClient(c++) #################################### ##FILL ME IN #################################### ## links to any required tutorials ## note.0= [[pt_BR/ROS/Tutorials/ExaminingPublisherSubscriber|examining the simple publisher and subscriber]] ## descriptive title for the tutorial ## title = Criando um Nó de Serviço-Cliente simples (C++) ## multi-line description to be displayed in search ## description = Neste tutorial é ensinado como escrever um Nó (node) de Serviço-Cliente em C++. ## the next tutorial description ## next = ## links to next tutorial ## next.0.link= [[pt_BR/ROS/Tutorials/ExaminingServiceClient|Examining the simple service and client]] ## next.1.link= ## what level user is this tutorial for ## level= BeginnerCategory #################################### <<IncludeCSTemplate(TutorialCSHeaderTemplate)>> <<Buildsystem()>> <<TOC(4)>> ##startpage == Fazendo um Nó de Serviço (service) == Criaremos um Nó de serviço ("add_two_ints_server") que irá receber dois números inteiros (ints) e retornaremos a soma destes. {{{{#!wiki buildsystem rosbuild Change directory into the beginner_tutorials package, you created previously in the [[ROS/Tutorials/CreatingPackage|creating a rosbuild package]] tutorial: {{{ roscd beginner_tutorials }}} }}}} {{{{#!wiki buildsystem catkin Mude o seu diretório atual para o pacote beginner_tutorials que você criou dentro do seu catkin workspace nos tutoriais prévios: {{{ roscd beginner_tutorials }}} }}}} Certifique-se que você seguiu as etapas corretas no tutorial anterior de como criar um serviço, [[ROS/Tutorials/CreatingMsgAndSrv#Creating_a_srv|creating the AddTwoInts.srv]] (tenha certeza de escolher a versão correta da ferramenta de construção (build) que você está usando, o mesmo pode ser consultado no link do topo da pagina wiki). === O Código === Crie o arquivo add_two_ints_server.cpp dentro da pasta /src dentro do pacote beginner_tutorials e cole o seguinte codigo dentro do arquivo .cpp: {{{ #!cplusplus block=service #include "ros/ros.h" #include "beginner_tutorials/AddTwoInts.h" bool add(beginner_tutorials::AddTwoInts::Request &req, beginner_tutorials::AddTwoInts::Response &res) { res.sum = req.a + req.b; ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b); ROS_INFO("sending back response: [%ld]", (long int)res.sum); return true; } int main(int argc, char **argv) { ros::init(argc, argv, "add_two_ints_server"); ros::NodeHandle n; ros::ServiceServer service = n.advertiseService("add_two_ints", add); ROS_INFO("Ready to add two ints."); ros::spin(); return 0; } }}} === O Código Explicado === Agora vamos entender o código! <<CodeRef(service,1,2)>> `beginner_tutorials/AddTwoInts.h` é o arquivo header gerado pelo arquivo .srv que haviamos criados anteriormente. <<CodeRef(service,4,5)>> Essa função provê o serviço para adicionar dois inteiros (ints), ele recebe uma requisição (do cliente) e responde (Response) com o tipo definido no arquivo .srv e retorna um booleano. <<CodeRef(service,6,11)>> Aqui os dois inteiros são adicionados e guardados na resposta (Response). Então algumas informações sobre a requisição (request) são guardadas, por último o serviço retorna verdadeiro quando este é completado. <<CodeRef(service,18,18)>> Aqui o serviço é criado e passado/avisado pelo ROS. == Escrevendo o Nó do Cliente == === O Código === Crie o arquivo add_two_ints_client.cpp dentro da pasta /src dentro do pacote beginner_tutorials e cole o seguinte codigo dentro do arquivo .cpp: {{{ #!cplusplus block=client #include "ros/ros.h" #include "beginner_tutorials/AddTwoInts.h" #include <cstdlib> int main(int argc, char **argv) { ros::init(argc, argv, "add_two_ints_client"); if (argc != 3) { ROS_INFO("usage: add_two_ints_client X Y"); return 1; } ros::NodeHandle n; ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints"); beginner_tutorials::AddTwoInts srv; srv.request.a = atoll(argv[1]); srv.request.b = atoll(argv[2]); if (client.call(srv)) { ROS_INFO("Sum: %ld", (long int)srv.response.sum); } else { ROS_ERROR("Failed to call service add_two_ints"); return 1; } return 0; } }}} === O Código Explicado === Agora vamos entender o código! <<CodeRef(client,15,15)>> Aqui criamos o cliente para o serviço `add_two_ints`. O objeto `ros::ServiceClient` é usado para chamar o serviço posteriormente. <<CodeRef(client,16,18)>> Aqui instanciamos uma classe de serviço autogerada e assinalamos valores para seu membro de requisição (request). Qualquer classe de serviço (service class) contém dois membros: `request` e `response`, também contém duas definições de classe: `Response` e `Request`. <<CodeRef(client,19,19)>> Aqui é onde de fato chamamos o serviço. Como as chamadas (calls) do serviço são bloqueadas, ele retornará uma única vez quando a chamada for feita . Se a chamada do serviço for sucedida, a função `call()` retornará verdadeiro e o valor em `srv.response` será válido. Se a chamada não for bem sucedida, `call()` retornará falso e o valor dentro da resposta (response) de `srv.response` será inválido. {{{{#!wiki buildsystem rosbuild == Dando build nos seus Nós == Novamente edite o CMakeLists.txt do seu pacote beginner_tutorials: {{{ $ rosed beginner_tutorials CMakeLists.txt }}} e adicione o seguinte no final do arquivo: {{{ rosbuild_add_executable(add_two_ints_server src/add_two_ints_server.cpp) rosbuild_add_executable(add_two_ints_client src/add_two_ints_client.cpp) }}} Isso irá criar dois executáveis, "add_two_ints_server" e "add_two_ints_client", que irão por padrão para o diretório "bin". Para mais informações de como usar CMake com ROS, veja [[CMakeLists]] Agora execute o comando make: {{{ $ make }}} }}}} {{{{#!wiki buildsystem catkin == Compilando seus Nós == De novo, edite o arquivo CMakeLists.txt no seu pacote beginner_tutorials localizado em `~/catkin_ws/src/beginner_tutorials/CMakeLists.txt` e adicione o seguinte pedaço de código ao final do arquivo: <<GetTaggedCode(https://raw.github.com/ros/catkin_tutorials/master/create_package_srvclient/catkin_ws/src/beginner_tutorials/CMakeLists.txt,xml,SRVCLIENT,show_uri,no_tag_newlines,global_lines)>> Isto irá criar dois executáveis `add_two_ints_server` e `add_two_ints_client`, que irão por padrão no diretório do seu pacote do catkin workspace:[[catkin/workspaces#Development_.28Devel.29_Space|devel space]], localizado de forma padronizada em `~/catkin_ws/devel/lib/<nome do pacote>`. Você pode inicializar executáveis diretamente no terminal indo até sua localização ou pode usar o comando rosrun para iniciá-los. Eles não são colocados no '<prefix>/bin' pois isto poluiria o PATH quando você fosse instalar o seu pacote no sistema. Se você quiser que seu executável esteja no PATH na hora da instalação, você pode determinar um alvo (target) na configuração de instalação, veja: [[catkin/CMakeLists.txt]] Para uma descrição mais detalhada do arquivo [[catkin/CMakeLists.txt|CMakeLists.txt]] veja: [[catkin/CMakeLists.txt]] Agora rode `catkin_make`: {{{ # In your catkin workspace cd ~/catkin_ws catkin_make }}} }}}} Se o seu build falhar por alguma razão: * make sure you have followed the directions in the previous tutorial: [[ROS/Tutorials/CreatingMsgAndSrv#Creating_a_srv|creating the AddTwoInts.srv]]. {{{#!wiki buildsystem rosbuild * type `rosls beginner_tutorials/srv_gen/cpp/include/beginner_tutorials/` and check that the `.h` file matches the include in the client and server `.cpp` files. }}} == Rodando os Nós == Para rodar os Nós necessita-se que você tenha o ROS core inicializado. Abra um novo terminal e digite: {{{ roscore }}} Se tudo ocorrer bem, você deve ter uma saída resultante do comando como essa abaixo: {{{ ... logging to /u/takayama/.ros/logs/83871c9c-934b-11de-a451- 001d927076eb/roslaunch-ads-31831.log ... loading XML file [/wg/stor1a/rosbuild/shared_installation/ros/tools/roslaunch/roscore.xml] Added core node of type [rosout/rosout] in namespace [/] started roslaunch server http://ads:54367/ SUMMARY ====== NODES changing ROS_MASTER_URI to [http://ads:11311/] for starting master locally starting new master (master configured for auto start) process[master]: started with pid [31874] ROS_MASTER_URI=http://ads:11311/ setting /run_id to 83871c9c-934b-11de-a451-001d927076eb +PARAM [/run_id] by /roslaunch +PARAM [/roslaunch/uris/ads:54367] by /roslaunch process[rosout-1]: started with pid [31889] started core service [/rosout] +SUB [/time] /rosout http://ads:33744/ +SERVICE [/rosout/get_loggers] /rosout http://ads:33744/ +SERVICE [/rosout/set_logger_level] /rosout http://ads:33744/ +PUB [/rosout_agg] /rosout http://ads:33744/ +SUB [/rosout] /rosout http://ads:33744/ }}} Agora está tudo pronto para rodarmos o servidor e o cliente. === Rodando o Servidor === {{{{#!wiki buildsystem catkin Começe rodando o servidor, abra um novo terminal e digite: {{{ rosrun beginner_tutorials add_two_ints_server }}} Você deve ver algo similar como: {{{ Ready to add two ints. }}} }}}} === Rodando o Cliente === {{{{#!wiki buildsystem catkin Agora vamos rodar o cliente com os argumentos necessários, em outro terminal (shell) {{{ $ rosrun beginner_tutorials add_two_ints_client 1 3 }}} No shell do cliente você deve ver algo como: {{{ Sum: 4 }}} Já no shell do servidor você deve ver algo como: {{{ request: x=1, y=3 sending back response: [4] }}} }}}} ##endpage Agora que você escreveu um Serviço-Cliente simples, vamos para [[ROS/Tutorials/ExaminingServiceClient|examine the simple service and client]]. ## ROSTutorialCategory