ROS 节点通信

 "节点(Node)" 是ROS中指代连接到ROS网络的可执行文件的术语。接下来,我们将会创建两个节点,一个是发布器节点("talker"),它将不断的在ROS网络中广播消息;另一个是接收节点("listener"),从ROS网络中接收("talker")节点发送的信息。

//发布节点

 

#include "ros/ros.h"
#include "std_msgs/String.h"
int main(int argc, char **argv)
{
  ros::init(argc, argv, "talker");//创建发布消息的节点。名字为talker

  ros::NodeHandle n;//为这个进程的节点创建一个句柄。

  ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
/*告诉master我们将要在chatter topic上发布一个std_msgs/String的消息。这样master就会告诉所有

订阅了chatter topic的节点,将要有数据发布。第二个参数是发布序列的大小。在这样的情况下,如

果我们发布的消息太快,缓冲区中的消息在大于1000个的时候就会开始丢弃先前发布的消息。*/

 ros::Rate loop_rate(10);
/*ros::Rate对象可以允许你指定自循环的频率。它会追踪记录自上一次调用Rate::sleep()后时间的流

逝,并休眠直到一个频率周期的时间。在这个例子中,我们让它以10hz的频率运行。*/
 int count = 0;

/*roscpp会默认安装一个SIGINT句柄,它负责处理Ctrl-C键盘操作——使得ros::ok()返回FALSE。
ros::ok()返回false,如果下列条件之一发生:
SIGINT接收到(Ctrl-C)
被另一同名节点踢出ROS网络
ros::shutdown()被程序的另一部分调用
所有的ros::NodeHandles都已经被销毁
一旦ros::ok()返回false, 所有的ROS调用都会失效。*/
 while (ros::ok())
     {
        /*我们使用一个由msg file文件产生的‘消息自适应’类在ROS网络中广播消息。现在我们使  

      用标准的String消息,它只有一个数据成员"data"。当然你也可以发布更复杂的消息类型*/。
       std_msgs::String msg;
       std::stringstream ss;
      ss << "hello world " << count;
      msg.data = ss.str();
       ROS_INFO("%s", msg.data.c_str());
  
     chatter_pub.publish(msg);//现在我们已经向所有连接到chatter topic的节点发送了消息。
    ROS_INFO("%s", msg.data.c_str());//ROS_INFO和类似的函数用来替代printf/cout.

    ros::spinOnce();
      /*在这个例子中并不是一定要调用ros::spinOnce(),因为我们不接受回调。然而,如果你想拓

展这个程序,却又没有在这调用ros::spinOnce(),你的回调函数就永远也不会被调用。所以,在这里最

好还是加上这一语句。*/

    loop_rate.sleep();//这条语句是调用ros::Rate对象来休眠一段时间以使得发布频率为10hz。
     ++count;
     }
}


对上边的内容进行一下总结:
初始化ROS系统
在ROS网络内广播我们将要在chatter topic上发布std_msgs/String消息
以每秒10次的频率在chatter上发布消息
接下来我们要编写一个节点来接收消息。

 


 

#include "ros/ros.h"
#include "std_msgs/String.h"
        /*这是一个回调函数,当消息到达chatter topic的时候就会被调用。消息是以 boost 

shared_ptr指针的形式传输,这就意味着你可以存储它而又不需要复制数据*/
void chatterCallback(const std_msgs::String::ConstPtr& msg)
   {
     ROS_INFO("I heard: [%s]", msg->data.c_str());
   }
int main(int argc, char **argv)
   {
	ros::init(argc, argv, "listener");
	ros::NodeHandle n;
        /*告诉master我们要订阅chatter topic上的消息。当有消息到达topic时,ROS就会调用

chatterCallback()函数。第二个参数是队列大小,以防我们处理消息的速度不够快,在缓存了1000个

消息后,再有新的消息到来就将开始丢弃先前接收的消息。*/


	ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
/*NodeHandle::subscribe()返回ros::Subscriber对象,你必须让它处于活动状态直到你不再想订阅该

消息。当这个对象销毁时,它将自动退订 上的消息。*/

	ros::spin();
/*ros::spin()进入自循环,可以尽可能快的调用消息回调函数。如果没有消息到达,它不会占用很多

CPU,所以不用担心。一旦ros::ok()返回FALSE,ros::spin()就会立刻跳出自循环。这有可能是

ros::shutdown()被调用,或者是用户按下了Ctrl-C,使得master告诉节点要shutdown。也有可能是节

点被人为的关闭。*/
	return 0;
    }


下边,我们来总结一下:
初始化ROS系统
订阅chatter topic
进入自循环,等待消息的到达
当消息到达,调用chatterCallback()函数

 

最后,在多个节点同时运行的时候,可以新打开一个终端,输入如下指令来观察节点的通信图。

$rqt_graph



 

转载于:https://www.cnblogs.com/zhubaohua-bupt/p/7182810.html

### ROS 节点间的通信机制 在机器人操作系统 (ROS) 和其后续版本 ROS 2 中,节点之间的通信主要通过消息传递的方式完成。这种设计允许分布式系统的组件彼此独立运行并交换数据。 #### 主题(Topic)通信 主题是一种异步的消息广播方式,在其中多个发布者可以向同一主题发送消息,而订阅该主题的节点会接收到这些消息[^1]。这种方式非常适合于传感器数据流或其他高频率更新的信息共享场景。 ```python import rclpy from std_msgs.msg import String def main(args=None): rclpy.init(args=args) node = rclpy.create_node('minimal_publisher') publisher = node.create_publisher(String, 'topic', 10) msg = String() i = 0 def timer_callback(): nonlocal i msg.data = f'Hello World: {i}' i += 1 publisher.publish(msg) timer_period = 0.5 # seconds timer = node.create_timer(timer_period, timer_callback) try: while rclpy.ok(): rclpy.spin_once(node) except KeyboardInterrupt: pass node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() ``` 上述代码展示了如何创建一个简单的发布者节点来定期发布字符串消息到名为 `topic` 的主题上。 #### 服务(Service) 除了主题之外,另一种常见的通信模式是请求-响应模型的服务调用。在这种情况下,客户端发出特定请求给服务器端,后者处理后返回结果[^4]。 #### 动作(Action) 对于长时间的任务执行反馈需求,则可采用动作框架。它不仅提供了目标设定功能还支持进度监控以及取消操作等功能[^3]。 当遇到 **ROS 节点间通讯问题** 时,通常可以从以下几个方面排查: 1. 网络配置错误:确保所有涉及网络传输的部分都正确设置了主机名解析和防火墙规则。 2. 版本兼容性差异:由于提到过 `[引用2]` 所述关于不同版本之间可能存在不一致的情况,请确认所使用的库文件是否匹配当前环境下的依赖关系。 3. 参数调整不当:某些高级特性比如服务质量(QoS),如果未合理设置可能会导致预期外的行为表现出来。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值