rosnode中使用xmlrpc建立topic之间链接的一些知识点

rosmaster是一个中转。

每个node都是从roscpp中继承了一堆东西。

1. topic的消息如何来的

当一个nodesubscribe一个topic时,该node就会建立一个subscription结构。含有一个subscriptionQueue,用来保存收到的msg.

谁往queue里面填冲消息?



首先了解一下TransportPublisherLink, 对于一个clientnode来说,他说subscribe的topic有很多publisher,他们可能是别的进程,TransportPublisherLink就是他们在clientnode进程内部的一个代表。

TransportPublisherLink来了数据,当那些publisher向该topic发送消息时,本clientnode对应的TransportPublisherLink::onMessageLength就被触发了,说明来数据了:



->TransportPublisherLink::onMessageLength,callback是绑定在一个connection上的。当该transportconnection上有数据时,就会调用此callback.

->TransportPublisherLink::onMessage,继而会触发此函数

->TransportPublisherLink::handleMessage,publisher_link的作用就是收到消息后转发给关联的subscription.

->Subscription::handleMessage,这个函数将该消息放入subscriptionqueue, 并且往callbackQuque里面插入一个callback,该callback会异步的被callbackQuqueManager的thread处理,callbackQueueManager维护一些workerthread, 这些workerthread会从callbackQueue里面取出一个callback执行,执行时,会从subscriptionqueue里面取出消息数据来处理。

->SubscriptionQueue::push并callback_queue_->addCallback

2 TransportPublisherLink的建立

好了,知道了,是TransportPublisherLink受到消息后,向subscriptionQueue和callbackQueue里面插入信息了,那么TransportPublisherLink怎么建立的,他如何收到消息的?



我们根据movebase的一个/move_base_simple/goal的topic来说起。

Move base node 会subscribe该topic,而运行于pc上的rviz会向该topic发送消息。用来告诉movebase目的地。

大体流程是:

1. move base启动后subscribe到该topic,此时rviz还没有启动。movebase node 会见里subscription结构

2. 当rviz启动后,rviz会链接到rosmaster

3. rosmaster 得知rviz会advertise该topic,于是就会使用python实现的xmlrpc远程调用接口调用publisherUpdate来通知clientnode有puhlisher更新。

4. client node这边收到xmlrpc的远程过程调用,会调用绑定在该remoemethod上的callback.

TopicManager::pubUpdateCallback(XmlRpc::XmlRpcValue& params,XmlRpc::XmlRpcValue& result),这个callback是通过xmlrpc_manager_->bind("publisherUpdate",boost::bind(&TopicManager::pubUpdateCallback, this, _1, _2));绑定的。那么这个callback干了什么?这样clientnode就知道有publisher来了。才能和rviz建立通知,并且clientnode能够知道来者的ip和port,以便于直接和publisher建立p2p链接,而不用rosmaster中转。

这个callback会

TopicManager::pubUpdate(const string&topic, const vector<string> &pubs)会根据topic找到对应的subscription并将新的publisher列表告诉subscription.

->Subscription::pubUpdate() ,subscription首先检查新来的publisher是否已经建立链接了,如果没有,会开始建立链接:

->Subscription::negotiateConnection这里尝试和新的publisher协商,并建立一个pendingConnection.当协商结束,pendingConnection的callback会被调用,最后成为一个正常的connection.

具体过程是:首先建立一个XmlRpcClient(peer_host,peer_port,"/", );然后调用他的XmlRpcClient::executeNonBlock(constchar* method, params)执行”requestTopic”这个rpc.这个过程是异步的。会立刻返回。那么这个远程过程调用就会发给rviz, rviz接受后,就有结果回来,就会有异步的callback通知给xmlRpcClient.

再具体一点xmlRpcClient的executeNonBlock先建立和rviz的链接,建立socket,然后建立异步connect.然后prepare一份request,这个request包含了要被远程调用的method和参数。但是并不马上发送。有专门的角色完成该工作。此时,xmlRpcClient维护了一个socket,并且也有一份request数据。,他把自己注册给XmlRpcDispatch,由xmlRpcDispatch的work()函数负责检查该fd有没有数据io,并处理数据。检查工作在一个xmlRPCManager的线程中执行:

XMLRPCManager::serverThreadFunc()

-》XmlRpcServer::work,简单调用xmlRpcDispatch::work

-》XmlRpcDispatch::work,dispatcher维护一个sourcelist, 他select各个xmlrpcsource的fd,看有没有读写事件发生,如果有,就掉用source的handleEvent处理。xmlrpcsource实际上封装了一个socketfd. 而xmlRpcClient就是一个xmlRpcSource,并且被注册进来了。

-》XmlRpcClient::handleEvent,这个函数会发送request,也会接受response.

->writeResponse

->XmlRpcSocket::nbWrite



上面提到,Subscription::negotiateConnection会建立pendingConnection,这些connection会被添加到XMLRPCManager::instance()->addASyncConnection(conn);里面。



XMLRPCManager::serverThreadFunc()除了负责触发socket的io,还负责不断检查pendingconnection是否已经完成。



voidXMLRPCManager::serverThreadFunc()这个函数是一个循环,他不断检查所有的connection,调用他们的check()函数:

-》PendingConnection::check(),检查pendingConnection是否已经ok,已经建立链接,如果是就回调subscription。而check实际是通过检查XmlRpcClient::executeCheckDone(XmlRpcValue&result)函数来实现的,该函数实际上检查connectionState是否_IDLE,那么connectionState何时成为_IDLE?当然是收到了request的结果了。我们知道XmlRpcCLient::handleEvent会处理socketio,如果收到了结果,继而会调用到XmlRpcClient::readResponse(),这个函数就会把connectionState设置为_IDLE.

一旦pendingConnection被检查发现完成了工作,就掉用:

->void Subscription::pendingConnectionDone(constPendingConnectionPtr& conn, XmlRpcValue&result),这个函数会建立如下几个物体:

TransportTCPPtr transport(newTransportTCP(&PollManager::instance()->getPollSet()));

if (transport->connect(pub_host,pub_port)) //链接topic.

{

ConnectionPtr connection(newConnection()); //connection对象

TransportPublisherLinkPtr pub_link(newTransportPublisherLink(name_,shared_from_this(), xmlrpc_uri,transport_hints_));



connection->initialize(transport, false,HeaderReceivedFunc());

pub_link->initialize(connection);



ConnectionManager::instance()->addConnection(connection);



boost::mutex::scoped_lock lock(publisher_links_mutex_);

addPublisherLink(pub_link);

}

可见,这里就是建立了connection了。

3 后面有时间可以看看connection,ConnectionManager, TransportTCP的管理



ROS C++中NodeHandle生命周期与通信资源管理详解 NodeHandle是ROS C++节点通信的核心上下文管理器,其本质并非语法糖,而是控制Publisher/Subscriber注册、命名空间隔离与资源生命周期的权限代理。它基于引用计数机制与XML-RPC会话绑定ROS Master,决定了话题能否被发现、参数能否被正确读取。理解其构造方式(默认/私有/子命名空间/父子派生)直接关系到节点可维护性与多实例兼容性;而作用域管理不当将导致‘节点在线但无通信’这一高频故障。本文聚焦NodeHandle在工业级ROS系统中的工程实践,涵盖生命周期安全模式、多线程 阅读详情

相关推荐

ROS Melodic安装避坑指南:Ubuntu 18.04环境配置全解析

ROS(Robot Operating System)是一套面向机器人开发的中间件框架,其核心依赖于操作系统、编译工具链与通信运行时的精密协同。ROS Melodic作为ROS 1系列最后一个长期支持(LTS)版本,专为Ubuntu 18.04深度适配,涵盖内核、GCC、Python 2.7及关键库(如Boost、PCL、OpenCV)的版本对齐,确保二进制兼容性与工业级稳定性。该组合显著降低新手入门门槛,避免因ABI不兼容、GPG密钥失效、rosdep映射缺失或LD_LIBRARY_PATH污染导致的隐性

weixin_33892359的博客 360

ROS_Xmlrpc++ 简单示例

根据 https://www.ibm.com/developerworks/cn/webservices/ws-xml-rpc/代码修改而来: XmlRpc 简单代码示例 operations.h:  #ifndef OPERATIONS  #define OPERATIONS  class operations {  public:   int add();   oper

linuxarmsummary的专栏 2028

SAP MM | 批次管理:OMCT 批次级别设置与自动寻批机制

SAP批次管理中的批次级别(OMCT配置)是核心设置,决定批次号的唯一性范围。推荐选择“物料级别唯一”,避免跨工厂调拨问题;若配置错误,后期修改需复杂数据转换。此外,通过SD模块的自动批次决定功能(VCH1策略),可实现FIFO/FEFO出库规则,需后台激活并配置查找策略。批次管理需跨模块协作(MM/PP/SD),确保从生产到出库的全流程精准追踪。**关键点:**批次级别需在项目初期锁定,避免后期修改风险。

RiverRia的专栏 963

Handle消息机制解析

概述 Handler消息机制(由Handler/Looper/MessageQueue等构成),Android有大量的消息驱动方法来进行交互,就像Android的四大组件(Activity、Service、Broadcast、ContentProvider)的启动过程交互,都离不开Handler的消息机制,所以Android系统某种意义上说也是一种以消息驱动的系统。 架构图 相应的类 Handler Handler概述 Handler是一个可以通过关联一个消息队列来发送和处理消息,.

qq_25504577的博客 884

电容DAC版图布局中的对称艺术:从二维共质心到误差最小化

本文深入探讨了电容DAC版图布局中的对称艺术,重点介绍了二维共质心技术如何有效最小化误差。通过分析系统误差和随机误差的来源,详细解析了共质心布局的核心技术及优化策略,包括梯度误差补偿和寄生参数平衡方法。实战案例展示了该技术在12位SAR ADC设计中的应用效果,为高精度集成电路设计提供了重要参考。

weixin_29300241的博客 584

洛谷 P5736 【深基7.例2】质数筛

题目描述 输入 n(n\le100)n(n≤100) 个不大于 100000 的整数。要求全部储存在数组中,去除掉不是质数的数字,依次输出剩余的质数。 输入格式 无 输出格式 无 输入输出样例 输入 #1 复制 5 3 4 5 6 7 输出 #1 复制 3 5 7 板子题,使用一下线性筛 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using n

qq_37978559的博客 1118

跟着阿杰slam 入门学习--Gmapping离线重演bag文件

学到这里,我有点记不清gmapping是哪来的了,所以我就翻以前的视频,发现不管是hector_mapping还是gmapping,都需要先install安装下来,这个课程是wpr_simulation就已经包含hector_mapping了,所以只需要去github里搜索wpr_simulation,然后复制下载网址,输入git clone 网址,就可以克隆了。gmapping同理。lskip:每采纳一个数据数值,就会跳过n个,n=lskip的值,当lskip=2时,会采纳1,4,7序号的测距值。

yuchenhuaizhe的博客 992

基于STM32与OV7670的嵌入式视频监控系统设计与实现

本文详细介绍了基于STM32单片机与OV7670摄像头的嵌入式视频监控系统设计与实现。从硬件选型、电路设计到软件开发,涵盖了摄像头驱动、TFT显示优化及图像处理等关键技术,提供了实用的调试技巧和性能优化方案,为低成本、高效率的视频监控系统开发提供完整解决方案。

desk3的博客 804

ROS参数服务器实战:跨节点配置管理与热更新原理

参数服务器是ROS中实现节点间统一配置管理的核心机制,本质是一个运行在Master上的分布式键值缓存,支持跨进程、跨机器的参数共享与运行时动态更新。其设计解决了硬编码配置不可变、环境变量难维护、文件加载无实时性等工程痛点,技术价值体现在模块化封装(private命名空间)、低延迟访问(getParamCached缓存机制)和层级化治理(URI路径式组织)。典型应用场景包括PID控制器热调参、多传感器标定同步、仿真到实车参数迁移等。本文深入解析参数类型约束(如double不支持NaN)、YAML加载陷阱、C+

weixin_33829657的博客 437

Confluence安装Drawio插件

记录confluence安装drawio插件步骤

devotedwife的博客 7381

金融行业软件测试面试题(含答案)

6、假如发现了一个BUG,跟开发本身没什么关系,涉及到理念,需求问题,如何解决?11、假如要你测试6个月期限的p2p借款产品,你应该怎么设计案例,说出测试点。17、如果京东有一个购物网页给你,你要怎么进行测试?31、我们公司自动化测试用的语言是Java,Java你不会,该怎么办?23、你们测试用的测试环境是谁给的?24、如果领导分配你的任务超出负荷,领导高估了你的能力,怎么办。26、给你一个模块测试,只有一个星期的时间你如何有效率地完成?29、如果你组长的用例写错了,但他认为是对的,你怎么处理?

crhnb的博客 918

ROS C++开发必学:NodeHandle核心原理与工业级实践

NodeHandle是ROS C++通信机制的基石,本质是一个有状态、带作用域的资源管理器,而非简单句柄。它封装节点注册、话题/服务生命周期、回调队列调度及参数服务器访问等关键能力。理解其构造方式(默认/命名空间/父子嵌套/自定义队列)、作用域语义与析构行为,是避免Segmentation fault、Failed to contact master等高频崩溃的前提。在机器人系统中,合理运用多命名空间NodeHandle和独立回调队列,可实现传感器、执行器与控制逻辑的线程安全隔离。本文聚焦ROS 1(ros

weixin_33928137的博客 326

后仿之 SDF优先级和相关概念

综上:在后仿中,工具(vcs)看起来对于negative interconnect的处理如下:a. 查看此negative INTERCONNECT语句所对应的destination cell中是否有PORT语句:b. 如果PORT delay的值大于等于INTERCONNECT的绝对值,就从PORT中消耗掉对应的负值。c. 如果PORT delay不够用,就查看destination cell中是否有IOPATH或DEVICEm有IOPATH或DEVICE,并且够用(任意一种够用就行),就消耗掉。

qq_24434431的博客 1108

ros 框架解析-订阅部分

本文从roscpp源码的角度解析ros框架的订阅部分,目的是分析订阅相关的各个类的关系和作用,从而熟悉ros订阅功能底层调用过程,和ros节点之间的通信方式。源码地址是https。

良晨的技术站 1050

PCL RANSAC拟合直线并插值

空间直线线性插值的原理与实现方法。

点云侠的博客 137

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

ROS源码阅读:话题通信建立与消息传递

ROS即机器人操作系统(Robot Operating System),但是ROS本身并不是一个操作系统,而是一个软件库和工具集;ROS为简化机器人开发设计了一整套通信机制(话题、服务、参数、动作),通过这套机制可以将机器人的各个组件连接起来从而解决了机器人各个组件的通信问题;ROS中的通信方式主要包括话题通信、服务通信和参数管理器,其中话题通信在三种通信方式中应用最为广泛。

weixin_39427234的博客 910

WINCC7.3破解文件

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

ROS服务与客户端:远程procedurecall

1.背景介绍 1. 背景介绍 Robot Operating System(ROS)是一个开源的软件框架,用于构建和操作多种类型的机器人。ROS提供了一系列的工具和库,以便开发者可以轻松地构建和操作机器人系统。在ROS中,服务(services)和客户端(clients)是两种重要的组件,它们用于实现远程过程调用(Remote Procedure Call,RPC)。 本文将深入探讨ROS服...

AI天才研究院 916

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

ros melodic源码分析之消息订阅subscribe

一个简单的订阅程序如下: File: /home/lgy/ros_catkin_ws/src/ros_tutorials/roscpp_tutorials/listener/listener.cpp 29: #include "ros/ros.h" 30: #include "std_msgs/String.h" 36: void chatterCallback(const std_msgs::String::ConstPtr& msg) 37: { 38: ROS_INFO("I hear

weixin_45609638的博客 1751

xmlrpc笔记

类的结构图如下: 数据发送类 XmlRpcDispatch client,server都用使用此类发送数据。 客户端 XmlRpcClient 构造函数为:  XmlRpcClient(const char* host, int port, const char* uri=0);//参数1为IP,参数2为端口。 execute():  bool execute(const char

evsqiezi 1778

mysql role

mysql8.0才有角色的概念。

zj88189748的专栏 547

ROS XmlrpcNode 接口测试

XmlrpcNode 服务器端class MyFuncs: def div(self,x,y): return x%y def add(self,x,y): return x+y import logging import select import socket try: import _thread except ImportErr

linuxarmsummary的专栏 2048

ROS 中功能包的安装与查询

摘自:https://blog.youkuaiyun.com/m0_37972797/article/details/86531041?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=205fa6f2-fdae-4912-b2df-41ee22cd0967&depth_1-utm_source=distribute.pc_relevant.

自主无人机 PX4 ROS SLAM 路径规划 MVS等技术分享 8959

一起自学SLAM算法:1.5 ROS节点通信

前面已经学习了大量ROS的基础知识,到这里终于可以开始编写ROS代码了,并在实战中体验和理解ROS的真正面容。ROS代码的编写围绕节点通信过程中的消息机制和消息类型两个核心点展开,因此先详细阐述话题(topic)、服务(service)和动作(action)三种消息机制的原理,然后介绍这三种消息机制中使用的消息类型,最后利用C++编写分别使用这三种消息机制通信的代码实例。话题通信方式是单向异步的,发布者只负责将消息发布到话题,订阅者只从话题订阅消息,发布者与订阅者之间并不需要事先确定对方的身份,话题充当消息

机器人研究猿-优快云 1818

ROS学习(三):消息通信过程

主节点管理节点信息,每个节点根据需要与其他节点进行连接和消息通信。在这里, 我们来看看最重要的主节点、节点、话题、服务和动作信息的过程。 一.运行主节点 节点之间的消息通信当中,管理连接信息的主节点是为使用ROS必须首先运行的必需 元素。ROS 主节点使用roscore命令来运行,并使用XMLRPC运行服务器。主节点为了节点与节点的连接,会注册节点的名称、话题、服务、动作...

kh815的博客 1302

ROS学习之 roscpp内部架构概况

wiki链接:http://wiki.ros.org/roscpp/Internals     这部分包括一个对roscpp内部架构组织高度概括的审视,从最底层开始。     1.通用哲学     roscpp的哲学是仅仅使一部分API对外可见。这意味着公共的头文件不允许包含私有的头文件。     这意味着在最初时发生很多类型擦除。(???)     通常我们会尽量减小包含的外部头文

shiyue0010的专栏 2776
上一篇: urdf的例子分析
下一篇: movebase导航和地图数据的使用 - 1 move base overview
csshell2002
博客等级 码龄11年 30粉丝 41原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值