ROS 详细讲解通过键盘控制小海龟运动来实现话题发布者Publisher与订阅者Sbuscriber

Tani ·
更新时间:2024-11-15
· 654 次阅读

// linear线性的 angular角度的
//%0.2f打印geometry_msgs::Twist类型
// %s打印std_msgs::String类型

文章目录==发布者Publisher与订阅者Sbuscriber====第一步启动小海龟及其键盘控制====第二步查看rosnode节点直接的关系====第三步查看发布消息的列表====第四步创建发布者Publishser====发布者运行结果:====第五步创建订阅者Sbuscriber====订阅者运行结果:====扩展:发布hello_n_word并订阅====第一步:模拟发布者====第二步:模拟订阅者====运行结果:== 发布者Publisher与订阅者Sbuscriber

// linear线性的 angular角度的
%0.2f打印geometry_msgs::Twist类型

第一步启动小海龟及其键盘控制

启动小海龟及其键盘控制

$ roscore $ rosrun turtlesim turtlesim_node $ rosrun turtlesim turtle_teleop_key 第二步查看rosnode节点直接的关系

查看rosnode节点直接的关系

$ rqt_graph

rqt_graph
由于箭头是单向的,所以消息传播是单向的,由图像可知,/teleop_turtle为发布者Publisher,用于键盘发布指令,/turtlesim为订阅者Subscriber,用于定义指令,两节点的通信管道为/turtle/cmd_vel,只要实现一个发布者在通信管道/turtle/cmd_vel发送相应信息都会被订阅者订阅,下面将介绍如何查看发布消息的类型

第三步查看发布消息的列表

查看发布消息的列表

$ rosnode list

查看发布消息的类型
我们可以看到发布者/teleop_turtle

然后输入下列指令

$ rosnode info /teleop_turtle

然后输入下列指令我们可以看到

Publications: * /rosout [rosgraph_msgs/Log] * /turtle1/cmd_vel [geometry_msgs/Twist]

其中 /turtle1/cmd_vel [geometry_msgs/Twist]是我们要的信息
以 /turtle1/cmd_vel消息管道,以geometry_msgs::Twist传递消息

Services: * /teleop_turtle/get_loggers * /teleop_turtle/set_logger_level

这里面可以看到/teleop_turtle,该为发布者的节点名

第四步创建发布者Publishser

创建发布者Publishser

//以 /turtle1/cmd_vel消息管道,以geometry_msgs::Twist传递消息 // /teleop_turtle,该为发布者的节点名 // linear线性的 angular角度的 //%0.2f打印geometry_msgs::Twist类型 #include "ros/ros.h" #include "geometry_msgs/Twist.h" int main(int argc, char **argv){ //初始化ros节点 ros::init(argc, argv, "Publisher");//也可以将Publisher改为/teleop_turtle //创建节点句柄 ros::NodeHandle node; //创建一个发布者Publisher,消息管道/turtle1/cmd_vel,消息类型geometry_msgs::Twist ros::Publisher pub = node.advertise("/turtle1/cmd_vel",1000); //设置一个循环频率每秒5次 ros::Rate loop_rate(5); //计数发布次数 int count = 0; while (ros::ok()){ //初始化消息类型geometry_msgs::Twist geometry_msgs::Twist msg; msg.linear.x = 5; msg.angular.z = 1; //发布消息 pub.publish(msg); //发布成功在该节点终端显示 //已成功发布第%d条消息,发布的内容为%0.2f打印geometry_msgs::Twist类型 ROS_INFO("Successfully published message %d with:[msg.linear.x = %0.2f m/s , msg.angular.z = %.2f rad/s]" ,count , msg.linear.x, msg.angular.z); loop_rate.sleep(); ++count; } return 0; } 发布者运行结果:

创建Publishser

第五步创建订阅者Sbuscriber

创建订阅者Sbuscriber
创建订阅者由图像可知,消息管道为/turtle1/cmd_vel
消息类型为geometry_msgs::Twist

* /turtlesim/get_loggers * /turtlesim/set_logger_level

节点名为/turtlesim

/* * 消息管道为/turtle1/cmd_vel 消息类型为geometry_msgs::Twist * 节点名为 /turtlesim */ #include "ros/ros.h" #include "geometry_msgs/Twist.h" void cmdCallBack(const geometry_msgs::Twist& msg){ //将收到的消息打印出来 ROS_INFO("The message I received was:[x=%0.2f m/s, z=%0.2f rad/s]" , msg.linear.x, msg.angular.z); } int main(int argc, char **argv){ //初始化ros节点 ros::init(argc, argv, "Subscriber");//节点名也可以写成/turtlesim //创建节点句柄 ros::NodeHandle node; //创建一个Subscriber,消息管道为/turtle1/cmd_vel,注册回调函数为cmdCallBack ros::Subscriber sub = node.subscribe("/turtle1/cmd_vel", 1000, cmdCallBack); ros::spin(); return 0; } 订阅者运行结果:

运行结果

扩展:发布hello_n_word并订阅

通过上面的内容实现,不通过小海龟信息管道,自己定义一个,来实现发布者发布hello_n_word ,n为数字并打印在自己终端,订阅者接收并打印出该消息。

第一步:模拟发布者 //以 /talker消息管道,以std_msgs::String传递消息 // /Publisher,该为发布者的节点名 // %s打印std_msgs::String类型 #include "sstream" #include "ros/ros.h" #include "std_msgs/String.h" int main(int argc, char **argv){ //初始化ros节点 ros::init(argc, argv, "Publisher"); //创建节点句柄 ros::NodeHandle node; //创建一个发布者Publisher,消息管道/turtle1/cmd_vel,消息类型std_msgs::String ros::Publisher pub = node.advertise("/talker",1000); //设置一个循环频率每秒5次 ros::Rate loop_rate(5); //计数发布次数 int count = 0; while (ros::ok()){ ++count; //初始化消息类型std_msgs::String std_msgs::String msg; std::stringstream ss; ss<< "hello_"<< ++count<<"_world"; msg.data = ss.str(); //发布消息 pub.publish(msg); //发布成功在该节点终端显示 //已成功发布第%d条消息,发布的内容为%s打印std_msgs::String类型 ROS_INFO("Successfully published message with:[%s]",msg.data.c_str()); loop_rate.sleep(); } return 0; } 第二步:模拟订阅者 /* * 消息管道为/talker 消息类型为std_msgs::String * 节点名为 /Subscriber */ #include "sstream" #include "ros/ros.h" #include "std_msgs/String.h" void cmdCallBack(const std_msgs::String::ConstPtr& msg){ //将收到的消息打印出来 ROS_INFO("The message I received was:[%s]",msg->data.c_str()); } int main(int argc, char **argv){ //初始化ros节点 ros::init(argc, argv, "Subscriber"); //创建节点句柄 ros::NodeHandle node; //创建一个Subscriber,消息管道为/turtle1/cmd_vel,注册回调函数为cmdCallBack ros::Subscriber sub = node.subscribe("/talker", 1000, cmdCallBack); ros::spin(); return 0; } 运行结果:

运行结果
运行结果


作者:李德龙杰



海龟 ros publisher 运动

需要 登录 后方可回复, 如果你还没有账号请 注册新账号