ROS2核心概念之代码示例二

上一节主要写了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++,不熟悉的,可以来这里学习学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值