ROS话题—之发布学习

这里简单的记录一下在ros系统中如何实现一个发布者,仅对新手,老司机可以以直接忽略啦!

首先我个人认为发布有两种情况 :一种是发布已有功能包中的数据类型,比如我们可以发布turtlesim功能包中已经存在的数据类型。另一种是发布自己创建的消息数据类型。后者需要自己在自己所建的功能包下面建立一个msg文件夹,并且在这个文件夹下建立一个.msg文件,这个msg文件中用来存放我们个人所想要发布的数据类型。今天我重点来讲述总结前者。

先说一下创建一个已有消息类型发布者的完整步骤

1:创建一个工作空间 并进行编译

2:在这个工作空间的src目录下 创建一个功能包 这点要注意  加上依赖项  roscpp  rospy  std_msgs   geometry_msgs turtlesim   后面两个我不太清楚为什么加进来 可能是因为 我们使用turtlesim功能包中的数据类型才加进来吧,不过这不是重点。

3:创建一个publisher.cpp文件  开始书写程序即可。 下面是程序书写步骤

第一步:初始化节点  给节点起一个名字  告诉节点管理器 我来了   并创建节点句柄 这基本是所有话题通讯会做的事,这个节点名字可以随便取 ,但是最好比较有明显的含义吧

             ros::init(argc,argv,"节点名字");

             ros::NodeHandle n;

第二部:创建一个发布者  这里发布者的名字可以随便取  好记有意思即可   这里包括了消息类型和话题名字  请想一下我们怎么确定消息类型和话题名字呢?下面这句话是固定套路 记住就行  Publisher是大写  后面  advertise也记住 这都是发布消息的基本语句内容。

             ros::Publisher  发布者 = n.advertise<消息类型>("话题名字",队列长度);

第三部:设置循环的频率  括号中是多少 就是每秒多少次

             ros::Rate loop_rate(10);

第四部:进入while(ros::ok())循环   创建消息实例  发布消息即可  后面加上循环等待  

            这里的程序要根据消息的数据类型来写 ,这里不做介绍 在下面的代码中会有体现 

            loop_rate.sleep();

看似到这里已经很完美了 ,网上的多数教程也是这样做的,但是请原谅我是个菜鸡,我在编写程序的时候依然是云里雾里,直到现在我也不太明白 。我把我知道这些东西记录下来 防止忘记。

重点来了:从最开始说起 ,刚开始说话 我们发布的是turtlesim这个功能包中已有的消息类型 那么这个包里有哪些数据类型?每个数据类型又是依赖那个话题进行通讯的呢?每个数据类型内部结构又究竟是怎么定义的呢?带着这些东西我们去寻找答案  啦啦啦啦啦啦

首先打开一个新的终端 运行rosrun turtlesim turtlesim_node 这个节点   这时候我们便可以使用相应的命令来查看上面的问题了。

首先我们要知道我们在哪个话题上进行发布  使用rostopic  list即可  可以看到 

关于海龟的三个话题 /turtle1/cmd_vel    /turtle1/color_sensor     /turtle1/pose  
      那么这三个话题所对应的消息类型又是什么呢  我们可以通过 rostopic type +话题名字进行查看  得到如下结果 
      rostopic type  /turtle1/cmd_vel            --->geometry_msgs/Twist
      rostopic type  /turtle1/color_sensor       --->turtlesim/Color
      rostopic type  /turtle1/pose               --->turtlesim/Pose

假设我们选择 /turtle1/cmd_vel  进行发布消息 那么请问还记得吗 ?这个话题进行发布包含了两个头文件

#include "ros/ros.h"     #include "geometry_msgs/Twist.h"     

我刚学的时候 一直好奇后面那个头文件是怎么找出来的,原来就是用  rostopic type  /turtle1/cmd_vel 这个东西找出来的 也就是这个消息类型是geometry_msgs::Twist  

这里我们二货一下  为什么网上的教程在写发布程序的时候 都选择 这个话题  而不是其他两个呢?我就傻逼的遇到了这个问题,我选择了那个颜色的话题,程序通过编译  没有问题   然后运行海龟节点  和这个发布的节点  发现海龟的背景颜色根本没有改变,原因是

后来 运行了 rqt_graph这个命令 发现两个节点 根本没有建立通讯联系  
使用  rosnode info turtlesim   之后  发现 turtlesim这个节点的详细信息中  后面那两个话题是海归节点发布的话题  海归节点订阅的是第一个话题    所以绝对不会有反应的!!!!

下面说在while中创建发布实例的问题   我们知道了消息类型 但是并不知道消息的具体内部定义,这时候我们可以使用 

rosmsg show geometry_msgs/Twist
      
      geometry_msgs/Vector3 linear
        float64 x
        float64 y
        float64 z
      geometry_msgs/Vector3 angular
        float64 x
        float64 y
        float64 z
        
        rosmsg show turtlesim/Color
        uint8 r
        uint8 g
        uint8 b
        
        rosmsg show turtlesim/Pose
        float32 x
        float32 y
        float32 theta
        float32 linear_velocity
        float32 angular_velocity

最后一点  写完程序之后 要添加编译连接语句。

这样我们就可以创建实例了,差不多就是这些内容 下面我把源码放上 ,刚学没两天  说的术语都不太对 大家见谅  欢迎拍砖

#include "ros/ros.h"
#include "geometry_msgs/Twist.h"
int main(int argc,char **argv)
{     
	 //初始化节点  创建节点句柄  告诉节点管理器 老娘来了      
	 ros::init(argc,argv,"publish_color");     
	 ros::NodeHandle n;            
	 ros::Publisher pub_color = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",10);           
	 //设定循环频率       
	 ros::Rate loop_rate(10);      
	 unsigned char count=0;     
	 while(ros::ok())      
	 {            
		 geometry_msgs::Twist v_msg;           
		 v_msg.linear.x=0.2;            
		 v_msg.linear.y=0.6;           
		 v_msg.linear.z=0.4;                      
		 v_msg.angular.x=0.2;            
		 v_msg.angular.y=0.6;            
		 v_msg.angular.z=0.3;                       
		 pub_color.publish(v_msg);            
		 ROS_INFO("v_msg.linear.x:%lf  v_msg.linear.y:%lf  v_msg.linear.z:%lf", v_msg.linear.x, v_msg.linear.y, v_msg.linear.z); 
		 loop_rate.sleep();      
	 }      
	 return 0;   
 }
#include "ros/ros.h"
#include "learing_topic_server/Person.h"
int main(int argc,char ** argv)
{      
      //初始化节点
      ros::init(argc,argv,"person_publish");
      ros::NodeHandle n;
      //创建发布函数
     ros::Publisher person_pub=n.advertise<learing_topic_server::Person>("person_info",10);
      //设置循环频率
      ros::Rate loop_rate(10);
      while(ros::ok())
      {
            learing_topic_server::Person people;
            people.name = "GUO";
            people.sex =1;
            people.age =24;
       
            person_pub.publish(people);
            loop_rate.sleep();
      }
      return 0;
}


#include "ros/ros.h"
#include "learing_topic_server/Person.h"
void personCallback(const learing_topic_server::Person::ConstPtr& person_msg)
{
      std::cout <<"subscriber is  succeddfully"<<std::endl;
      ROS_INFO("name:%s  age:%d  sex:%d",person_msg->name.c_str(),person_msg->age,person_msg->sex);
}

int main(int argc,char** argv)
{
      ros::init(argc,argv,"person_subscriber");
      ros::NodeHandle n;
      
      ros::Subscriber person_sub = n.subscribe("person_info",10,personCallback);
      
      ros::spin();
      return 0;
 }

 

 

 

 

 

 

 

          

            

 

 

 

 

 

 

 

 

 

 

 

 

 


 

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值