ROS话题通信
ROS通信机制
三种实现策略:
1.话题通信
2.服务通信年
3.参数服务器
话题通信理论模型
角色:
1.master
2.talker
3.listener
流程
master可以根据话题建立发布者和订阅者之间的连接。
0.talker提交自身信息:话题
1.listener提交自身信息:话题
2.
注意:
1.使用的协议由RPC和TCP
2.步骤0和1没有顺序关系
3.talker和listener都可以存在多个
4.talker和listerner建立连接后,master就可以关闭了
5.上述实现流程已经封装了,以后直接调用即可
话题通信应用时的关注点:
1.大部分实现已经被封装了
2.话题设置
3.关注发布者的实现
4.关注订阅者的实现
5.关注消息载体
C++实现话题通信
1.代码实现
发布方代码:
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
/*
发布方实现:
1.包含头文件;
ROS中的文本类型 ---> std_msgs/String.h
2.初始化ROS节点;
3.创建节点句柄;
4.创建发布者对象;
5.编写发布逻辑并发布数据
*/
int main(int argc, char *argv[])
{
setlocale(LC_ALL,""); //解决中文乱码问题
// 2.初始化ROS节点;
ros::init(argc,argv,"talker");
// 3.创建节点句柄;
ros::NodeHandle nh;
// 4.创建发布者对象;
ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10); //话题为chatter
// 5.编写发布逻辑并发布数据
//先创建被发布的消息
std_msgs::String msg;
std::string msg_front = "Hello , 你好! "; //消息前缀
//设置编号
int count = 0;
//编写循环,循环中发布数据
ros::Duration(3).sleep();//延迟三秒发布数据,以防订阅端确实前几个数据
ros::Rate r(1);//设置发布频率
//question:###回调函数###
while (ros::ok())
{
//实现字符串拼接数字
std::stringstream ss;
ss << "hello ---"<<count;
msg.data = ss.str();
pub.publish(msg);
//添加日志:
ROS_INFO("talker发布的数据是 :%s",msg.data.c_str());
r.sleep();
count++;
ros::spinOnce();
}
return 0;
}
订阅方代码:
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
/*
订阅方实现:
1.包含头文件;
ROS中的文本类型 ---> std_msgs/String.h
2.初始化ROS节点;
3.创建节点句柄;
4.创建订阅者对象;
5.处理订阅数据
*/
void doMsg(const std_msgs::String::ConstPtr &msg){
//通过msg获取并操作订阅到的数据
ROS_INFO("listener订阅的数据:%s",msg->data.c_str());
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL,""); //解决中文乱码问题
// 2.初始化ROS节点;
ros::init(argc,argv,"listener");
// 3.创建节点句柄;
ros::NodeHandle nh;
// 4.创建订阅者对象;
ros::Subscriber sub = nh.subscribe("chatter",10,doMsg);
// 5.处理订阅数据
ros::spin();
return 0;
}
2. 配置CMakeLists.txt
add_executable(C++节名 src/源文件名称.cpp)
target_link_libraries(C++节名
${catkin_LIBRARIES}
)
3.编译执行
终端1:
roscore
终端2:
cd 工作空间
source ./devel/setup.bash
rosrun c++包名 C++节名
4.计算图
python实现话题通信
1.代码实现
发布方代码:
#! /usr/bin/env python
#coding:utf-8
#导包
import rospy
from std_msgs.msg import String
if __name__=="__main__":
#初始化ROS节点
rospy.init_node("talker")
#创建发布者
pub=rospy.Publisher("Chatter",String,queue_size=10)
#创建消息类型
msg=String()
#设置发布排频率
rate=rospy.Rate(1)
count=0
#休眠1秒,防止出现前面的数据没有接受到
rospy.sleep(1)
#循环发布数据,其中rospy.is_shutdown()的意思是只要节点关闭就返回true
while not rospy.is_shutdown():
count+=1
#str(count)可以将count转变为字符串
msg.data="hello"+str(count)
pub.publish(msg)
#rospy.loginfo()相当于C++版本里面的ROS_INFO()
rospy.loginfo("I talk %s",msg.data)
#休眠
rate.sleep()
订阅方代码:
#! /usr/bin/env python
#coding:utf-8
#导包
import rospy
from std_msgs.msg import String
def Callback(msg):
rospy.loginfo("I hear %s",msg.data)
if __name__=="__main__":
#初始化ROS节点
rospy.init_node("listener")
#创建订阅者
sub=rospy.Subscriber("Chatter",String,Callback,queue_size=10)
#回调函数
#spin
rospy.spin()
2. 配置CMakeLists.txt
catkin_install_python(PROGRAMS
scripts/demo02_pub.py
scripts/demo02_sub.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
3.编译执行
为py文件添加权限
在script中打开终端:chmod +x *.py
,ll
可以查看权限情况
编译后在工作空间终端执行
终端1:
roscore
终端2:
cd 工作空间
source ./devel/setup.bash
rosrun 包名 自定义文件名.py