ROS学习笔记之——消息的订阅与再发布

142 篇文章 179 订阅

在进行ros开发时,最基本的就是对消息进行订阅与发布。

在同一个节点里订阅和发布消息

本博文,暂时订阅ROS自带话题/odometry/filtered

并保存到文档中,同时将其发布~

直接给出代码如下

#include<ros/ros.h>
#include <geometry_msgs/Point.h>
#include <geometry_msgs/PointStamped.h>
#include <iostream>
#include <fstream>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <nav_msgs/Odometry.h>
// #include <boost/bind.hpp> 
// #include <stdio.h>

using namespace std;

class point_time
{
	//定义这个类的私有成员
	private:
		ros::NodeHandle n; 声明用于ROS系统和通信的节点句柄


		double t;
		double t_past;
		double t_now;
		int flag_past;

		//定义订阅者
		ros::Subscriber point_info_sub;

		//定义发布者与订阅者
		ros::Publisher point_info_pub;
		geometry_msgs::PointStamped ekf_point;

		//写入文件流(写入时间的)
		ofstream fout_time;

		//写入文件流(写入坐标的)--用统一的文件流就好
		// ofstream fout_point;


	//公有成员
	public:
		//定义其构造函数
		point_time()
		{
			t_past = 0;
			t_now = 0;
			flag_past = 1;
			t = 0;
			

			fout_time.open("time_odom_multi_location_ekf_xyz.txt");	//打开一个这样的文件

			fout_time << "x" << "\t" << "y" << "\t"<< "z" << "\t"<< "time" << endl;

			//订阅来自/odometry/filtered的话题
			//消息类型为nav_msgs::Odometry
			//通过函数pointCallback来调回
			point_info_sub = n.subscribe<nav_msgs::Odometry>("/odometry/filtered", 1000, &point_time::pointCallback, this);
			
			//发布一个名为/location_ekf_info的话题
			//消息类型为geometry_msgs::PointStamped
			point_info_pub=n.advertise<geometry_msgs::PointStamped>("/location_ekf_info", 1000);
		}

		void pointCallback(const nav_msgs::Odometry::ConstPtr &msgPointStamped)
		{
			nav_msgs::Odometry msgPoseStamped = *msgPointStamped;
			//接收到消息后,给到发布者(发布者是私有成员)
			ekf_point.point.x = msgPoseStamped.pose.pose.position.x;
			ekf_point.point.y = msgPoseStamped.pose.pose.position.y;
			ekf_point.point.z = msgPoseStamped.pose.pose.position.z;

			//给发布者的加入frameid和时间戳
			ekf_point.header.frame_id ="map";
			ekf_point.header.stamp = ros::Time::now();
			//在终端显示定位结果与时间
			ROS_INFO("(%.5f, %.5f, %.5f)", msgPoseStamped.pose.pose.position.x*100, msgPoseStamped.pose.pose.position.y*100, msgPoseStamped.pose.pose.position.z*100);
			cout << "coordinate_out_time:\t" << msgPoseStamped.header.stamp << "secs" << endl;
			
			//保存到文件中。
			fout_time << msgPoseStamped.pose.pose.position.x*100 <<"\t"<< msgPoseStamped.pose.pose.position.y*100 <<"\t"<< msgPoseStamped.pose.pose.position.z*100 << "\t";
			point_info_pub.publish(ekf_point);//发布出去

			//将时间差输出出来
			if(flag_past == 1)
			{
				t_past = msgPoseStamped.header.stamp.toSec();
				flag_past = 0;
				// fout_time << t << endl;
			}
			else
			{
				t_now = msgPoseStamped.header.stamp.toSec();
				flag_past = 1;
			}

			if (t_now != 0)
			{
				t = t_now - t_past;
				if (t_now > t_past)
				{
					t = t;
				}
				else
				{
					t = -t;
				}
				cout << "t_now - t_past = " << t << endl;
				fout_time << t << endl;
			}
			else 
			{
				t=0;
				cout << "t_now - t_past = " << t << endl;
				fout_time << t << endl;
			}
		}

		//构析函数
		~point_time()
		{
			fout_time.close();
			cout << "close file success!" << endl;
		}

};

int main(int argc, char **argv)
{
	ros::init(argc, argv, "ekf_translater");//初始化当前节点的名称(这个名字应该需要跟cmake.list设置的一样)
	// ros::NodeHandle n;

	point_time recordT;//定义了一个类

	// ros::Subscriber point_info_sub = n.subscribe<geometry_msgs::PointStamped>("/location_info", 1000, boost::bind(pointCallback,_1, t_past, t_now, flag_past));
	ros::spin();
	return 0;
}

在同一个节点里订阅和发布消息的另外一种方法

ROS 基础: 在同一个节点里订阅和发布消息_知行合一-CSDN博客

#include <ros/ros.h>
 
class SubscribeAndPublish
{
public:
  SubscribeAndPublish()
  {
    //Topic you want to publish
    pub_ = n_.advertise<PUBLISHED_MESSAGE_TYPE>("/published_topic", 1);
 
    //Topic you want to subscribe
    sub_ = n_.subscribe("/subscribed_topic", 1, &SubscribeAndPublish::callback, this);
  }
 
  void callback(const SUBSCRIBED_MESSAGE_TYPE& input)
  {
    PUBLISHED_MESSAGE_TYPE output;
    //.... do something with the input and generate the output...
    pub_.publish(output);
  }
 
private:
  ros::NodeHandle n_; 
  ros::Publisher pub_;
  ros::Subscriber sub_;
 
}//End of class SubscribeAndPublish
 
int main(int argc, char **argv)
{
  //Initiate ROS
  ros::init(argc, argv, "subscribe_and_publish");
 
  //Create an object of class SubscribeAndPublish that will take care of everything
  SubscribeAndPublish SAPObject;
 
  ros::spin();
 
  return 0;
}

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ROS1中的话题发布订阅是一种常用的通信机制,允许节点之间通过特定的话题(topics)进行数据交换和信息传递。发布者(publisher)节点负责发布数据到特定话题,而订阅者(subscriber)节点则负责订阅该话题并接收发布发布的数据。 在ROS1中,话题是一种基于消息(message)的通信方式。发布者和订阅者通过特定的消息类型进行通信。在给定的话题上进行订阅发布之前,需要先定义该话题的消息类型。 例如,我们可以使用ROS消息定义语言(msg)来定义一个名为"example"的消息类型,该消息类型具有两个字段"test1"和"test2"(引用和)。然后,我们可以使用这个消息类型来创建发布者和订阅者节点。 发布者节点的工作是在指定的话题上发布特定消息。在示例代码中,pub.cpp(引用)中的发布者节点定义了一个名为"/topic/example"的话题,并将消息类型设置为"example"。通过调用ros::Publisher对象的publish()函数,发布者可以将消息发送到该话题上。 订阅者节点的工作是在指定的话题上订阅并接收发布发布消息。在示例代码中,sub.cpp(引用)中的订阅者节点通过调用ros::Subscriber对象的subscribe()函数来订阅名为"topic/example"的话题,并且指定了一个名为subscriberCallback的回调函数来处理接收到的消息。在回调函数中,可以对接收到的消息进行相应的处理。 综上所述,ROS1中的话题发布订阅是通过定义消息类型、创建发布者和订阅者节点,并在特定的话题上进行发布订阅来实现的。发布者负责发布消息到话题,而订阅者则负责订阅该话题并接收发布发布消息。这种通信机制可以方便地实现节点之间的数据交换和信息传递。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值