用RoboWare Studio创建好工作区和package后,在src下新建两个cpp文件,一个做话题的发布者,另一个做话题的订阅者,然后编译下就可以测试运行了,不过RoboWare只能调试运行一个节点,另一个可以用自带的集成终端(ctrl+`)或者新开一个终端运行,当然也可以写一个launch启动文件。
发布者:
//ros/ros.h是一个实用的头文件,它引用了ROS系统中大部分常用的头文件
#include "ros/ros.h"
//std_msgs/String存放在std_msgs package里,由String.msg文件自动生成的头文件
#include "std_msgs/String.h"
#include <sstream>
int main(int argc, char **argv)
{
//初始化ROS,注意:名称必须唯一
ros::init(argc,argv,"example1_a");
//设置节点进程句柄
ros::NodeHandle n;
//告诉master我们将要在message topic上发布一个std_msgs/String的消息
//参数一为发布的话题的名称;
//参数二为缓冲区大小,如果我们发布的消息太快,缓冲区中的消息在大于1000个的时候就会开始丢弃先前发布的消息
//NodeHandle::advertise() 返回一个 ros::Publisher对象,它有两个作用:
//1) 它有一个publish()成员函数可以让你在topic上发布消息; 2) 如果消息类型不对,它会拒绝发布
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("message",1000);
//设置发送频率10Hz
//ros::Rate对象可以允许你指定自循环的频率,自上一次调用Rate::sleep()后时间的流逝,并休眠直到一个频率周期的时间
ros::Rate loop_rate(10);
//ros::ok()返回false,如果下列条件之一发生:
//1、SIGINT接收到(Ctrl-C)
//2、被另一同名节点踢出ROS网络
//3、ros::shutdown()被程序的另一部分调用
//4、所有的ros::NodeHandles都已经被销毁
while(ros::ok())
{
//创建消息变量
std_msgs::String msg;
std::stringstream ss;
ss << "Talker node sending message!";
msg.data=ss.str();
//ROS_INFO("%s",msg.data.c_str()); 类似printf,输出检验
//发布消息
chatter_pub.publish(msg);
//如果出现一个订阅者,ROS就会更新并读取所有主题
//ROS消息回调处理函数ros::spin() 和 ros::spinOnce(),两者区别在于
//前者调用后不会再返回,也就是你的主程序到这儿就不往下执行了,而后者在调用后还可以继续执行之后的程序
ros::spinOnce();
//休眠
loop_rate.sleep();
}
return 0;
}
订阅者:
#include "ros/ros.h"
//ros/ros.h是一个实用的头文件,它引用了ROS系统中大部分常用的头文件
#include "std_msgs/String.h"
//std_msgs/String存放在std_msgs package里,由String.msg文件自动生成的头文件
//回调函数,当message topic消息到达后会调用此函数
void sub_callback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I hear: [%s]",msg->data.c_str());
}
int main(int argc, char **argv)
{
//初始化ROS,注意:名称必须唯一
ros::init(argc, argv, "example1_b");
//设置节点进程句柄
ros::NodeHandle n;
//参数一为订阅的话题名称(message);
//参数二是消息缓存队列,这里设置为1000,即缓存了1000个消息后,如果由新的消息到达,则开始丢弃先前接收的消息;
//参数三为当收到消息后调用的函数名称(sub_callback)
ros::Subscriber sub = n.subscribe("message", 1000, sub_callback);
//ros::spin()进入自循环,可以尽可能快的调用消息回调函数
ros::spin();
return 0;
}
launch启动文件
<?xml version="1.0"?>
<launch>
<node name = "example1_a" pkg = "chapter2_tutorials" type = "example1_a"/>
<node name = "example1_b" pkg = "chapter2_tutorials" type = "example1_b"/>
</launch>
节点名、package包名字对应自己创建的进行更改,我的工作区东西比较多就不用tree列出来了。
将两个节点跑起来后,可以在终端输入rostopic echo /message 来查看话题发布的内容(message是我的话题名,可以根据自己的代码修改)。
图1、发布者
图2、订阅者
图3、工作区结构