ROS TOPIC通讯编程
由上图我们可知,ROS MASTER 统筹管理ROS系统信息的发布和订阅
上图是发送String Message. 用到了std_msgs::String
编程目的创建一个publisher,并循环发送string信息,以下是程序设计及实现细节思路
-
需要使用到的库
#include
#include “ros/ros.h”
#include “std_msgs/String.h” -
ROS节点初始化 ros::init(argc, argv, “string_publisher”)
-
创建节点句柄 ros::NodeHandle n
-
创建一个publisher (ros::Publisher name = n.advertise<消息类型>(“发布名”,频率))在此处消息类型是用std_msgs::String
-
设置循环频率 ros::Rate loop_rate(10);再由loop_rate.sleep();调用实现循环发布的延时
-
循环发送信息while中需要利用ros::ok()检测系统是否准备ok。准备ok为1,不ok为0
-
传递的是string信息类型可以使用std_msgs::String msg;创建一个msg结构体用于储存string
std::stringstream ss;将信息存储在ss内部,通过ss.str()导出
msg.data = ss.str(); -
最后由name.publish(msg);由创建的publisher的publish函数发出
程序如下
#include <sstream>
#include "ros/ros.h"
#include "std_msgs/String.h"
int main(int argc, char **argv){
ros::init(argc,argv,"string_publisher");
ros::NodeHandle n;
ros::Publisher string_pub = n.advertise<std_msgs::String>("string_pub",1000);
ros::Rate loop_rate(10);
int count;
while(ros::ok()){
std_msgs::String msg;
std::stringstream ss;
ss<<"hello bro"<<count;
msg.data = ss.str();
++count;
loop_rate.sleep();
string_pub.publish(msg);
}
}
接下来我们需要创建一个subscribe订阅者
在ros::Subscribe sub = n.subscribe(“订阅的topic名”,1000, 回调函数名);
ros::spin循环等待回调函数,回调函数的输入参数 const std_msgs::String::ConstPtr& msg
通过ROS_INFO打印出消息
ROS_INFO(“I heard: [%s]”, msg->data.c_str());
#include "ros/ros.h"
#include "std_msgs/String.h"
void subscribe_callback(const std_msgs::String::ConstPtr& msg){
ROS_INFO("I heard: [%s]", msg->data.c_str());
}
void main(int argc,char **argv){
ros::init(argc, argv, "string_publisher");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("string_pub", 1000, subscribe_callback);
ros::spin();
return 0;
}
CMakeLists.txt
add_executable (string_publisher src/string_punlisher.cpp)
target_link_libraries (string_publisher ${catkin_LIBRARIES})
add_executable (string_subscriber src/string_subscriber.cpp)
target_link_libraries (string_subscriber ${catkin_LIBRARIES})
以上均编译好了以后
roscore
rosrun ...... string_publisher
rosrun ...... string_subscriber
第二部分
ROS Service通信编程
第一部分如何实现一个服务器,程序设计的基本流程
Client通过节点发送request请求给Server,Server发送Response回给Client
涉及到的库函数
ros/ros.h
std_srvs/SetBool.h
-
初始化ros节点
-
创建节点句柄
-
创建一个server,注册回调函数print()ros::ServiceServer service = n.advertiseService(“print_string”, print); <"print_string"是server的名字>
-
循环等待回调函数ros::spin()
-
回调函数(bool类型的函数)
bool print (std_srvs::SetBool::Request &req, std_srvs::SetBool::Response &res) -
在回调函数中req.data中有没有数据请求,若有数据的传递,则将res.success = true, res.message = "print successfully"存储在res.message中
#include "ros/ros.h"
#include "std_srvs/SetBool.h"
bool print(std_srvs::SetBool::Request &req,
std_srvs::Setbool::Response &res){
if(req.data){
res.success = true;
res.message = "print successfully";
}
return true;
}
int main(int argc, char **argv){
ros::init(argc,argv,"string_server");
ros::NodeHandle n;
ros::ServiceServer service = n.advertiseService("message_server",print);
ros::spin();
return 0;
}
ROS实现一个客户端
创建client,service的消息类型std_srvs::SetBool
ros::ServiceClient client = n.serviceClient<std_srvs::SetBool>(“message_server”) 客户端与服务端建立链接
客户端要发送请求,请求就需要创建一个service消息类型
std_srvs::SetBool srv;
srv.request.data = true;再将利用client.call(srv)发送出去。
#include "ros/ros.h"
#include "std_srvs/SetBool.h"
int main(int argc, cahr ** argv){
ros::init(argc, argv, "string_client");
ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<std_srvs::SetBool>("message_server");
std_srvs::SetBool srv;
srv.request.data = true;
client.call(srv);
return 0;
}
CMakelists.txt
add_executable (string_server src/string_server.cpp)
target_link_libraries (string_server ${catkin_LIBRARIES})
add_executable (string_client src/string_client.cpp)
target_link_libraries (string_client ${catkin_LIBRARIES})