/** @brief ROS初始化函数。
*
* 该函数可以解析并使用节点启动时传入的参数(通过参数设置节点名称、命名空间...)
*
* 该函数有多个重载版本,如果使用NodeHandle建议调用该版本。
*
* \param argc 参数个数(n+1,其中那1个是自身)
* \param argv 参数列表
* \param name 节点名称,需要保证其唯一性,不允许包含命名空间
* 节点名称要唯一,否则重复启动,启动早的容易被覆盖
* ros::init_options::AnonymousName:避免同一个名称的节点多次启动,会追加时间的编码
* \param options 节点启动选项,被封装进了ros::init_options
*
*/
void init(int &argc, char **argv, const std::string& name, uint32_t options = 0);
初始状态:
//1 初始化ros节点
ros::init(argc,argv,"publisher");
改变后的状态
//1 初始化ros节点
ros::init(argc,argv,"publisher",ros::init_options::AnonymousName);
/**
* \brief 根据话题生成发布对象
*
* 在 ROS master 注册并返回一个发布者对象,该对象可以发布消息
*
* 使用示例如下:
*
* ros::Publisher pub = handle.advertise<std_msgs::Empty>("my_topic", 1);
*
* \param topic 发布消息使用的话题
*
* \param queue_size 等待发送给订阅者的最大消息数量
*
* \param latch (optional) 如果为 true,该话题发布的最后一条消息将被保存,并且后期当有订阅者连接时会将该消息发送给订阅者
一般在发送静态地图时,设置为 true,这时发送方仅需要发送一次,即可当接收方连接时,收到消息
*
* \return 调用成功时,会返回一个发布对象
*
*
*/
调用 latch 之前
//3 创建发布者对象
//ros::Publisher pub =nh.advertise<std_msgs::String>("fang",10);
调用 latch 之后
ros::Publisher pub = nh.advertise<std_msgs::String>("fang",10,true);
#include "ros/ros.h"
#include "std_msgs/String.h"
#include
int main(int argc,char *argv[]){
/*
init 方法中,有几个参数
argc:参数个数(n+1,其中那1个是自身)
argv:接收传递的参数
options: 可选项
name:节点名称要唯一,否则重复启动,启动早的容易被覆盖
ros::init_options::AnonymousName:避免同一个名称的节点多次启动,会追加时间的编码
*/
setlocale(LC_ALL,"");
//1 初始化ros节点
ros::init(argc,argv,"publisher",ros::init_options::AnonymousName);
//2 创建句柄
ros::NodeHandle nh;
/**
* \brief 根据话题生成发布对象
*
* 在 ROS master 注册并返回一个发布者对象,该对象可以发布消息
*
* 使用示例如下:
*
* ros::Publisher pub = handle.advertise("my_topic", 1);
*
* \param topic 发布消息使用的话题
*
* \param queue_size 等待发送给订阅者的最大消息数量
*
* \param latch (optional) 如果为 true,该话题发布的最后一条消息将被保存,并且后期当有订阅者连接时会将该消息发送给订阅者
一般在发送静态地图时,设置为 true,这时发送方仅需要发送一次,即可当接收方连接时,收到消息
*
* \return 调用成功时,会返回一个发布对象
*
*
*/
//3 创建发布者对象
//ros::Publisher pub = nh.advertise("fang",10);
ros::Publisher pub = nh.advertise<std_msgs::String>("fang",10,true);
//4 编写发布逻辑并发布数据
// 创建被发布的信息
std_msgs::String msg;
//定义频率
ros::Rate rate(10);
//设置编号
int count=0;
//可让发送数据前 休眠3秒 当作是注册到roscore的时间
//这样可保证订阅者 可 接收到前几个信息
ros::Duration(3).sleep();
//循环发布
while(ros::ok()){
count++;
std::stringstream ss;
ss << "hello ---> " << count;
msg.data = ss.str();
if(count <= 10){
pub.publish(msg);
//添加日志
ROS_INFO("发布的数据为: %s",ss.str().c_str());
}
rate.sleep();
//官方建议 主要用于调用回调函数
ros::spinOnce();
}
return 0;
}
#include "ros/ros.h"
#include "std_msgs/String.h"
void doMsg(const std_msgs::String::ConstPtr &msg){
ROS_INFO("subcribe msg: %s", msg->data.c_str());
}
int main(int argc, char *argv[]){
setlocale(LC_ALL,"");
//1 初始化ros节点
ros::init(argc,argv,"subcribe");
//2 创建句柄
ros::NodeHandle nh;
//3 创建发布者对象
ros::Subscriber sub = nh.subscribe("fang",10,doMsg);
//为了处理上面的回调函数
ros::spin();
return 0;
}
【注】这里的消息发布方即使 init 同名情况下,仍可发布,主要是因为在 ros::init 中添加了 ros::init_options::AnonymousName
先启动
roscore
然后再启动 发布节点,测试 latch 的作用,即发布者先发布,待发布者将十条数据发完,订阅者在启动,测试订阅者能否接收到信息。
source ./devel/setup.bash
rosrun plumbing_test(项目名) test01_pub_node(节点名)
然后再运行订阅节点
source ./devel/setup.bash
rosrun plumbing_test(项目名) test01_sub_node(节点名)