ROS1&&ROS2中间件机制——源码级别梳理与总结

ros2 代码结构及源码解析 一、ros2 软件架构 二、ros2 命令代码解析 1.ros2 action 源码解析 2.ros2 bag 源码解析 3.ros2 run 源码解析 4.ros2 launch 源码解析 三、ros2 相关模块介绍 fastrtsp 源码解析 阅读详情
Case1

ROS2如下代码,经常出现客户端发送异步请求没有收到回调的情况:

    std::unordered_map<std::string, NodeInf> TaskManager::getAllNodes() {
        if (!get_cur_host_nodes_status_cli_->wait_for_service(std::chrono::duration<double>(1))) {
            MOGO_WARN("cannot call service to get cur host nodes because of [/ssm/query_agent_state] is not available");
            return {};
        }

        get_cur_host_nodes_status_cli_->prune_pending_requests(); // 加上这一行解决问题
        auto request = std::make_shared<autopilot_msgs::srv::BinarySrv::Request>();
        auto response = std::make_shared<autopilot_msgs::srv::BinarySrv::Response>();
        std::vector<uint8_t> bytes(hostname_.begin(), hostname_.end());

	    request->req = bytes;

        bool hasCallBack = false;
	    using ServiceResponseFuture = mogo::Client<autopilot_msgs::srv::BinarySrv>::SharedFuture;
        auto response_received_callback = [this, &hasCallBack](ServiceResponseFuture future) {
            system_master::AgentInf agent_info;
            auto response = future.get();

            common::DeserializeProto(agent_info, response->resp);
            if (response->resp.size() == 1 && response->resp[0] == '0') {
                MOGO_WARN("the request host of req does not exist in the domain host maintained by ssm, the resp returned by ssm is [0]");
                return;
            }

            if (agent_info.agent_state() == system_master::AgentState::DISCONNECT) {
                MOGO_WARN("the node status of the agent may be changing and is unreliable");
                return;
            }

            auto nodes = agent_info.node();
            for (int i = 0; i < nodes.size(); i++) {
                auto node = nodes.Get(i);
                NodeInf node_inf;
                node_inf.node_name_ = node.node_name();
                node_inf.node_state_ = static_cast<NodeState>(node.state());
                nodes_mp_[node_inf.node_name_] = node_inf;
            }

            hasCallBack = true;
        };
        
        auto future_result = get_cur_host_nodes_status_cli_->async_send_request(request, response_received_callback); 
        
        // mogo::spin_until_future_complete(node_handle_.get_node(), future_result) == mogo::FutureReturnCode::SUCCESS) {
        //     MOGO_INFO("Received response: %s", response->data.c_str());
        // } else {
        //     MOGO_ERROR("Failed to get response within the timeout.");
        // }

        int count = 0;
        while (!hasCallBack) {
            usleep(10000);
            count++;
            if (!hasCallBack && count >= 100) {
                MOGO_ERROR("asynchronous callback timeout, the threshold of timeout is 1s, the time slice is 10ms");
                break;
            }
        }

	    return nodes_mp_;
    }

        在 ROS 2 中,prune_pending_requests() 是一个用于清理挂起请求的函数。它是 rclcpp::Client 类的成员函数,用于清理尚未完成的请求,以避免请求队列中的挂起请求堆积。

        在 ROS 2 中,客户端(Client)与服务端(Server)之间进行通信时,客户端可能会向服务端发送请求并等待响应。如果客户端发送的请求在一定时间内没有得到响应,这些请求就会被视为挂起请求。这可能发生在网络延迟、服务端故障或其他原因导致请求无法完成的情况下。

   prune_pending_requests() 函数的作用是清理这些挂起请求,以确保请求队列不会无限增长。当调用这个函数时,它会检查每个挂起请求的状态,并将超时的请求从队列中移除。

以下是一个示例代码,演示了如何使用 prune_pending_requests() 函数:

#include <rclcpp/rclcpp.hpp>

int main(int argc, char** argv) {
  rclcpp::init(argc, argv);
  auto node = std::make_shared<rclcpp::Node>("client_node");

  // 创建客户端
  auto client = node->create_client<example_interfaces::srv::AddTwoInts>("add_two_ints");

  // 发送请求(未得到响应)
  auto request = std::make_shared<example_interfaces::srv::AddTwoInts::Request>();
  request->a = 10;
  request->b = 20;
  auto future_result = client->async_send_request(request);

  // 在发送请求后,等待一段时间
  std::this_thread::sleep_for(std::chrono::seconds(5));

  // 清理挂起的请求
  client->prune_pending_requests();

  // 检查请求是否已完成
  if (future_result.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
    auto response = future_result.get();
    RCLCPP_INFO(node->get_logger(), "Result: %ld", response->sum);
  } else {
    RCLCPP_WARN(node->get_logger(), "Request timed out.");
  }

  rclcpp::shutdown();
  return 0;
}

        在上面的示例中,我们创建了一个客户端,向服务端发送请求,并在请求发送后等待一段时间。然后,我们调用 prune_pending_requests() 函数来清理挂起请求。最后,我们检查请求是否已完成,并根据结果进行相应的处理。

        请注意,prune_pending_requests() 函数需要运行在客户端的上下文中,因此需要在适当的地方调用该函数,例如在等待请求完成之前或之后。

        这个函数对于管理挂起请求队列很有用,可以防止队列无限增长,并确保及时处理请求超时的情况。

〖ROS2 源码解析〗rclcpp/src/rclcpp/node.cpp ROS2 源码解析:rclcpp/src/rclcpp/node.cpp 阅读详情

相关推荐

ROS2 DDS中间件(图文并茂+超详细)

DDS 的目标场景在端上,致力于使端上的应用可以更容易的进行通信,由于它的完全分布式架构,可以方便的将端上的应用拆分为多进程架构,从而提高端的容错能力。从产品定位角度来讲,它和 Chromium 中的 mojo 都是端上的通信中间件,只不过 mojo 不强调分布式,内部集成了更多的特定于端上的机制,比如句柄的传输,消息的缓存等。但由于 mojo 生于 Chromium,目前官方并没有把它独立出来,所以用起来比较不方便。而 DDS 或许可以在简单的场景下作为 mojo 的替代品。

weixin_39939185的博客 5282

ros2 topic 源码解析

ros2 命令加载过程 ros2 topic代码位置:ros2\src\ros2cli\ros2topic 最终运作在ros2topic文件中 setup.py 定义挂载点,加载命令的执行函数 from setuptools import find_packages from setuptools import setup package_name = 'ros2topic' setup( name=package_name, version='0.13.1', packages=f

liu-yonggang的专栏 3796

ROS2中间件

ROS2中间件

John_ToStr的博客 1868

Ros2 容器操作源代码C++详细教程(将多线程放到一个进程内运行)

Ros2 容器操作源代码C++详细教程(将多线程放到一个进程内运行)Talker + Listener

WDHDNRYX的博客 3493

ROS2底层机制&源码分析(含rcl and dds)

ROS2底层机制&源码分析

John_ToStr的博客 922

【ROS 2知识】关于通信中间件RMW

ROS 2 构建在 DDS/RTPS 之上,DDS/RTPS作为ROS的中间件,提供发现、序列化和传输。本文详细解释了使用 DDS 实现和/或 DDS 的 RTPS 有线协议背后的机理。

gongdiwudu的专栏 1万+

ROS源代码阅读(2)-网络参数初始化

ros源码阅读

lxj362343的博客 8322

【ROS2原理7】中间件和接口(interface)

本文描述了在 ROS 和特定中间件实现之间使用抽象中间件接口的基本原理。它将概述目标用例及其要求和约束。在此基础上解释了开发的中间件接口。

gongdiwudu的专栏 8436

ROS2软件架构全面解析-学习如何设计通信中间件框架

ROS(Robot Operating System) 2 是一个用于开发机器人应用的软件平台,也称为机器人软件开发工具包 (SDK)。ROS2是ROS1的迭代升级版本 ,最主要的升级点是引入DDS(Data Distribution Service)为基础的底层通信系统。 这篇博客中将介绍、分析ROS2通信中间件软件架构,并且分析其中优点

chinamaoge的博客 3661

QGIS实战:5分钟搞定谷歌地图、高德、天地图等多源地图加载(附最新图源URL)

本文详细介绍了如何在QGIS中快速加载谷歌地图、高德、天地图等多源地图,提供2023年验证可用的最新图源URL和配置步骤。从环境准备到高级技巧,涵盖国内外主流地图服务的完整解决方案,帮助用户提升GIS工作效率。

weixin_29210759的博客 1218

AI赋能传染病建模:从数据到动力学模型的本地实践指南

这次我们来看一个将 AI 与传染病动力学建模结合的前沿方向。想象一下,你手头有一份流感爆发的病例数据,传统的建模方法可能需要复杂的微分方程和大量的手动调参,而 AI 模型能否直接从数据中“学习”出传播规律,甚至自动跑通整个建模流程?这正是当前研究的热点。根据《Nature》的最新综述,人工智能正在重塑传染病流行病学建模,从参数推断、趋势预测到多源数据融合,AI 技术为解决传统建模中的计算瓶颈和数据难题提供了全新路径。 对于开发者、数据科学家或公共卫生领域的研究者而言,最关心的是:这套方法能不能在本地跑起来?

weixin_29051811的博客 298

〖ROS2 源码解析〗rclcpp_action/src/server_goal_handle.cpp

ROS2 源码解析:rclcpp_action/src/server_goal_handle.cpp

sinat_39783664的博客 1530

虚幻商城 蓝图汇总

虚幻引擎是一个非常强大和灵活的游戏开发工具,拥有众多的蓝图可以帮助我们更高效地工作。

一碗清深的博客 1507

ROS源代码学习 一、综述

2021SC@SDUSC ROS简介 Robot Operating System(ROS),中文名为机器人操作系统,是目前主流的智能机器人开发框架,底层驱动由C++编写,业务逻辑可由各种语言(比如Python)实现,并有面向安卓端提供控制智能机器人的手机APP开发的Java版本。ROS目前分为ROS1与ROS2两代,ROS1主要的运行平台为Linux Ubuntu,通讯系统为基于TCPROS/UDPROS的星型拓扑(Master-Node)结构,编译系统为基于CMake的Cat...

acsdnUser的博客 1178

AgentScope Java 入门:Spring AI Alibaba 与 AgentScope 的定位与区别

摘要:Spring AI Alibaba是阿里基于Spring AI开发的本地化AI应用框架,旨在服务Java开发者。它提供模型接入、函数调用、RAG等功能,并与阿里云基础设施深度集成。同时,阿里开源了多智能体框架AgentScope,其Java版(AgentScope-Java)专注于Agentic设计理念。两者将协同发展:Spring AI Alibaba侧重Spring生态集成,AgentScope-Java强化智能体能力。未来计划包括支持AgentScope、升级Admin平台,以及推进Server

SmartSi 1534

构建OneService:打造高效、安全、灵活的企业级数据服务平台

数据服务(OneService)作为统一的数据服务出口,实现了数据的统一市场化管理,有效地降低数据开放门槛的同时,保障了数据开放的安全。

数据与算法架构提升之路专栏 2107

【ROS2机器人入门到实战】 2.ROS2中间件DDS架构

执行中间件的一个关键途径是信息传递。ROS2为每家DDS供应商都开发了对应的DDS_Interface即DDS接口层,然后通过DDS Abstract抽象层来统一DDS的API。ROS1的中间件是ROS组织自己基于TCP/UDP机制建立的,为了维护该部分ROS1组织花费了大量的精力,但是依然存在很多问题。ROS2采用了第三方的DDS作为中间件,将DDS服务接口进行了一层抽象,保证了上层应用层调用接口的统一性。DDS的应用层通过DDS进行数据订阅发布,DDS通过传输层进行数据的收发。

生活不止眼前的苟且 1万+

从零开始利用树莓派+扬声器,实现简单的蓝牙音箱,手机连接放歌

树莓派4B自带蓝牙和Wifi, 无需外接 USB dongle;蓝牙最常见的应用是近距离传输数据,比如蓝牙传文件,蓝牙音箱等。正好家里有个普通的usb供电的便携音箱;本文用树莓派蓝牙+普通音箱,实现简单的蓝牙音箱。怎样理解这三层:可以类比Linux网络层:ALSA 类似网络驱动框架A2DP 类似TCP/UDP层PulseAudio 类似HTTP层的服务器,类比Apache而蓝牙连接类似http连接和会话;

南七小僧的学海无涯 2221

AMCL源码阅读(ros2版本)

阅读amcl_ros2版本源码 源码git地址:https://github.com/ros2/navigation.git 本人注释的git地址:https://github.com/adayimaxiga/cartographer_migrate_to_ros2/tree/master/amcl 这个amcl执行过程与ros1版本没啥区别 首先阅读amcl_node.cpp 主函数调...

adayimaxiga 2426

C# 实现 Modbus 通信全教程(支持 TCP 和 RTU,含完整错误处理)

环境准备:安装 NModbus4 库,明确设备参数(IP/串口、地址、数据类型);连接设备:TCP 用 TcpClient,RTU 用 SerialPort,注意超时和参数匹配;读写数据:根据数据类型调用对应方法(读保持寄存器用 ReadHoldingRegisters);错误处理:捕获连接、超时、协议等异常,针对性排查问题。掌握这些后,即可轻松实现与工业设备的 Modbus 通信,为上位机开发提供稳定的数据交互能力。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 2068

动画实例化:千人同屏不卡顿的秘密

是一种将大量相同骨骼结构的角色动画批量处理、批量渲染的技术。动画计算与渲染解耦,动画数据在CPU或GPU上批量计算,渲染时通过GPU Instancing一次性绘制大量角色。极大减少DrawCall,提升大规模角色(如MMO、RTS、群体AI等)动画的运行效率。动画Bake:编辑器下将所有动画片段Bake为骨骼矩阵纹理。实例参数管理:每个角色维护自己的动画状态、帧索引等。批量渲染:用DrawMeshInstancedIndirect等API批量渲染,Shader中采样骨骼数据。剔除与LOD。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 421

〖ROS2 源码解析〗rclcpp_action/src/server.cpp

ROS2 源码解析:rclcpp_action/src/server.cpp

sinat_39783664的博客 1269

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【ROS2】概念:高级-ROS 2 中间件实现

ROS 2 中间件实现目录DDS 中间件包的常用包ROS 中间件实现的结构ROS 中间件实现是一组实现某些内部 ROS 接口的包,例如rmw、rcl和rosidlAPI。DDS 中间件包的常用包当前所有的 ROS 中间件实现都基于完整或部分 DDS 实现。例如,有一个使用 RTI 的 Connext DDS 的中间件实现和一个使用 eProsima 的 Fast DDS 的实现。...

cxyhjl的博客 1026

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

ROS2 discover 线程源码解析

connext结构体。

qq_33089547的博客 434

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

ROS源码学习 六、MasterServer:Node、Topic&Service

2021SC@SDUSC 目录 一、写在前面 二、MasterServer简介 1、MasterServer 2、Node、Topic、Service 三、Service、Topic、Node相关源码分析 四、总结 一、写在前面 在之前的博客中,我们首先从RosCore开始分析,学习了ROS线程池的运行逻辑,并从MasterServer的基类XmlRpcServer中的WebServer入手分析了ROS实现不同节点功能协作的基础XML-RP...

acsdnUser的博客 1391

Silverlight测试——利用Ranorex实现数据驱动测试

最近这段时间一直很忙, 上次关于Jacklin提出WindowsPhone 7访问本地DataBase在XAP包无法操作问题. 我正在WP7上测试利用开源数据库DB4O和SiaqoDB方式来解决这个问题.关于这篇验证文章晚些时候会把验证的相关原理,代码以及验证中发现的问题整理出一篇文章 发出来. 本篇来说说关于Silverlight测试——利用Ranorex工具实现TestDataDriver[...

weixin_33859665的博客 246
上一篇: ROS2录包---工程疑难问题解决&&性能优化&&个人反思总结
下一篇: 录包crash问题排查以及解决
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ปรัชญา แค้วคำมูล

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值