ros2 foxy 学写简单的服务

零、前情提要

前面跟着写了第一个话题订阅的例子,参考用colcon和c++写自己的第一个ROS2包,这次跟着教程写服务--客户端的例子。
这次依旧是跟着官方的示例走的。 Writing a simple service and client (C++)
但是有些步骤可能就没有上一篇那么详细了。

一、创建文件夹和包

#dev_ws可以自己命名,但最好保留`_ws`的缩写标志。
mkdir -p dev_ws/src 

#进入源目录
cd dev_ws/src 

#创建包
ros2 pkg create --build-type ament_cmake cpp_srvcli --dependencies rclcpp example_interfaces

上面--build-type ament_cmake就不必说了,ros2写c++的声明构建方式,cpp_srvcli是包名,--dependencies rclcpp example_interfaces指依赖于rclcppexample_interfaces,主要是这个example_interfaces,暂时我还没有看太懂这儿。按愿意是提供了一个类似以下的.srv文件,叫做AddTwoInts.srv
接下来还有一个相关的头文件我也不甚了解,先在这里表示疑问。前两行是请求的参数,破折号下面是响应。

int64 a
int64 b
---
int64 sum

接下来是照常更新package.xml,怎么打开我就不再说了,基本上文本编辑器都行。修改或添加如下的行:

<description>C++ client server tutorial</description>
<maintainer email="you@email.com">Your Name</maintainer>
<license>Apache License 2.0</license>

二、写服务端代码

dev_ws/src/cpp_srvcli/src文件下下创建add_two_ints_server.cpp文件,填入以下代码:

//ros2相关的头文件
#include "rclcpp/rclcpp.hpp"

//相关的文件夹下面好像并没有找到这个hpp,只有对应的.srv
#include "example_interfaces/srv/add_two_ints.hpp"

//内存相关
#include <memory>

//从.srv文件搁置中按要求获得request,和response,并打印到命令行
void add(const std::shared_ptr<example_interfaces::srv::AddTwoInts::Request> request,
          std::shared_ptr<example_interfaces::srv::AddTwoInts::Response>      response)
{
  response->sum = request->a + request->b;  //!约定运算方式
  RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Incoming request\na: %ld" " b: %ld",
                request->a, request->b);  //!看起来是获得要求的数据
  //在命令行输出运算的结果
  RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "sending back response: [%ld]", (long int)response->sum);
}

/******************************************************************************
 * @brief 主函数
 * @param  argc             My Param doc
 * @param  argv             My Param doc
 * @return int 
 ******************************************************************************/
int main(int argc, char **argv)
{
  rclcpp::init(argc, argv);//!初始化

  //创建node并命名
  std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_ints_server");

  //创建服务,这个也和依赖相关性太大了,这个反正也太麻烦了
  rclcpp::Service<example_interfaces::srv::AddTwoInts>::SharedPtr service =
    node->create_service<example_interfaces::srv::AddTwoInts>("add_two_ints", &add);

  //打印准备信息
  RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Ready to add two ints.");

  //绑定节点
  rclcpp::spin(node);
  rclcpp::shutdown();
}

三、写客户端代码

dev_ws/src/cpp_srvcli/src目录下创建add_two_ints_client.cpp文件

//ros2相关
#include "rclcpp/rclcpp.hpp"
#include "example_interfaces/srv/add_two_ints.hpp"

//系统相关
#include <chrono>   //!计时相关
#include <cstdlib>  //!集中特殊变量类型或者宏相关
#include <memory>   //!内存及指针相关

using namespace std::chrono_literals;

int main(int argc, char **argv)
{
  rclcpp::init(argc, argv); //!初始化

    //判断参数个数,方便进行输入和计算
  if (argc != 3) {
      RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "usage: add_two_ints_client X Y");
      return 1;
  }

    //创建节点
  std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_ints_client");
  //创建客户端,记得要和服务端同名
  rclcpp::Client<example_interfaces::srv::AddTwoInts>::SharedPtr client =
    node->create_client<example_interfaces::srv::AddTwoInts>("add_two_ints");

    //获得结构体信息和数据
  auto request = std::make_shared<example_interfaces::srv::AddTwoInts::Request>();
  request->a = atoll(argv[1]);
  request->b = atoll(argv[2]);

    //一分钟内搜寻服务端,如果没有找到,继续找,中间可以用Ctrl+C中断,并打印错误信息
  while (!client->wait_for_service(1s)) {
    if (!rclcpp::ok()) {
      RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
      return 0;
    }
    RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
  }
    
    //发送数据,并设置返回的格式
  auto result = client->async_send_request(request);
  // Wait for the result.
  if (rclcpp::spin_until_future_complete(node, result) ==
    rclcpp::FutureReturnCode::SUCCESS)
  {
    RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Sum: %ld", result.get()->sum);
  } else {
    RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Failed to call service add_two_ints");
  }

  rclcpp::shutdown();
  return 0;
}

修改CMakeLists.txt,最后简化后可能就只有这么点

cmake_minimum_required(VERSION 3.5)
project(cpp_srvcli)

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(example_interfaces REQUIRED)

add_executable(server src/add_two_ints_server.cpp)
ament_target_dependencies(server
  rclcpp example_interfaces)

add_executable(client src/add_two_ints_client.cpp)
ament_target_dependencies(client
  rclcpp example_interfaces)

install(TARGETS
  server
  client
  DESTINATION lib/${PROJECT_NAME})

ament_package()

四、生成和运行

我是在vs code里面添加了colcon tasks工具,Ctrl+shift+P选择构建工具为colcon以后,直接Ctrl+shift+B进行构建了,然后就可以到裕兴一步了,也可以按照官方的的方式进行构建
官方构建,首先,回到dev_ws文件夹目录下,检查依赖并构建

rosdep install -i --from-path src --rosdistro foxy -y #检查依赖
colcon build --packages-select cpp_srvcli #构建

运行,打开两个terminal,两个都输入如下source

. install/setup.bash

在其中一个里面运行服务端

ros2 run cpp_srvcli server

会得到如下输出

[INFO] [rclcpp]: Ready to add two ints.

在另一个里面会运行客户端,其中2,3是创给服务端让服务端进行计算的数。

ros2 run cpp_srvcli client 2 3

如果你输入的是2和3,则客户端得到的返回应该是这样的

[INFO] [rclcpp]: Sum: 5

而服务端打印的信息应该是这样的

[INFO] [rclcpp]: Incoming request
a: 2 b: 3
[INFO] [rclcpp]: sending back response: [5]

总体上是这样

运行效果

总结

那个.srv文件有点奇妙,而且用法很繁琐

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容