上一节主要写了Node,Topic的代码示例,这一节继续写未写完的。
ROS2之代码示例
service
不废话了,直接上代码;想看文字相关的内容,可以去看之前的介绍,写的也不太多。代码都是来自于古月居的代码,可以去blilili看他的视频。
// 创建回调函数,执行收到请求后对数据的处理
void adderServer(const std::shared_ptr<learning_interface::srv::AddTwoInts::Request> request,
std::shared_ptr<learning_interface::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);
}
// ROS2节点主入口main函数
int main(int argc, char **argv)
{
// ROS2 C++接口初始化
rclcpp::init(argc, argv);
// 创建ROS2节点对象并进行初始化
std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("service_adder_server");
// 创建服务器对象(接口类型、服务名、服务器回调函数)
rclcpp::Service<learning_interface::srv::AddTwoInts>::SharedPtr service =
node->create_service<learning_interface::srv::AddTwoInts>("add_two_ints", &adderServer);
RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Ready to add two ints.");
// 循环等待ROS2退出
rclcpp::spin(node);
// 关闭ROS2 C++接口
rclcpp::shutdown();
}
来看下client,如下图:
int main(int argc, char **argv)
{
// ROS2 C++接口初始化
rclcpp::init(argc, argv);
if (argc != 3) {
RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "usage: service_adder_client X Y");
return 1;
}
// 创建ROS2节点对象并进行初始化
std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("service_adder_client");
// 创建服务客户端对象(服务接口类型,服务名)
rclcpp::Client<learning_interface::srv::AddTwoInts>::SharedPtr client =
node->create_client<learning_interface::srv::AddTwoInts>("add_two_ints");
// 创建服务接口数据
auto request = std::make_shared<learning_interface::srv::AddTwoInts::Request>();
request->a = atoll(argv[1]);
request->b = atoll(argv[2]);
// 循环等待服务器端成功启动
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);
// 接收服务器端的反馈数据
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");
}
// 关闭ROS2 C++接口
rclcpp::shutdown();
return 0;
}
细心的可以看到,当中有段代码learning_interface::srv::AddTwoInts,这个是一个专门的模块,放在Interface里;这里是service的代码,主要是服务器创建的service,客户端创建的client,相当于客户端发送了一个请求,服务器返回这个请求;至于通信协议,并不是由service定义的,这个在中间件中,这个慢慢写,总有一天会写到的。
interface
来看下刚才的interface中怎么定义的?
int64 a # 第一个加数
int64 b # 第二个加数
---
int64 sum # 求和结果
这个就是消息之间的定义,就是一个数据结构;这个还有很多,后边还有,慢慢聊。
这一篇主要是讲了Service的代码,包括中间通信用的数据结构,这里是interface里的;只是提到了service里用的,后边还有很多,慢慢来。代码很简单,多看几遍,就懂了。代码量跟UE4/5源码量比,差了很多;不过不管是UE还是ROS2,都要先熟悉C++,不熟悉的,可以来这里学习学习。

603

被折叠的 条评论
为什么被折叠?



