文章

ROS学习记录(一):话题通信的基本操作

话题通信的基本操作(C++)

需求:
1
编写发布订阅实现,要求发布方以10HZ(每秒10次)的频率发布文本消息,订阅方订阅消息并将消息内容打印输出。
分析:

在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:

  1.发布方
  2.接收方
  3.数据(此处为普通文本)

流程:

  1.编写发布方实现;
  2.编写订阅方实现;
  3.编辑配置文件;
  4.编译并执行。

1.发布方
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#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,"test_pub");
    // 3.创建节点句柄
    ros::NodeHandle nh;
    // 4.创建发布对象
    ros::Publisher pub = nh.advertise<std_msgs::String>("test_pubsub",10);
    // 5.编写发布逻辑并发布数据
    //先创建被发布的消息
    std_msgs::String msg;
    //发布频率
    ros::Rate rate(10);
    //设置编号
    int count = 0;
    //编写循环,循环中发布数据
    while (ros::ok())
    {
        count++;
        //实现字符串拼接数据
        std::stringstream ss;
        ss<< "hello ---> " << count;
        msg.data = ss.str();
        pub.publish(msg);
        //添加日志
        ROS_INFO("发布的数据是:%s",ss.str().c_str());
        //休眠时间为1/f
        rate.sleep();
    }
    
    return 0;
}

2.订阅方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include"ros/ros.h"
#include"std_msgs/String.h"
/*
    发布实现:
        1.包含头文件
            ROS下的文本类型 ---> std_msgs/String.h
        2.初始ros节点
        3.创建节点句柄
        4.创建订阅对象
        5.处理接收到的数据 
        6.spin()函数
*/
//编写回调函数
void test_sub_callback(const std_msgs::String::ConstPtr &msg){
    //通过msg读取订阅到的数据
    ROS_INFO("订阅的数据:%s",msg->data.c_str());
}
int main(int argc, char *argv[])
{
    //设置编码
    setlocale(LC_ALL,"");
    //2.初始ros节点
    ros::init(argc,argv,"test_sub");
    //3.创建节点句柄
    ros::NodeHandle nh;
    //4.创建订阅对象
    ros::Subscriber sub = nh.subscribe("test_pubsub",10,test_sub_callback);
    //5.处理订阅到的数据
    ros::spin();
    return 0;
}

3.配置 CMakeLists.txt

1
2
3
4
5
6
7
8
add_executable(test_pub src/test_pub.cpp)
add_executable(test_sub src/test_sub.cpp)
target_link_libraries(test_pub
  ${catkin_LIBRARIES}
)
target_link_libraries(test_sub
  ${catkin_LIBRARIES}
)

4.执行

1.启动 roscore;

2.启动发布节点;

3.启动订阅节点。

5.注意要点

补充1. vscode 中的 main 函数 声明 int main(int argc, char const *argv[]){},默认生成 argv 被 const 修饰,需要去除该修饰符

补充2. 订阅时,第一条数据丢失 原因: 发送第一条数据时, publisher 还未在 roscore 注册完毕 解决: 注册后,加入休眠 ros::Duration(3.0).sleep(); 延迟第一条数据的发送

补充3. publisher与subscriber中的消息名称应当一样,且在ros网络中唯一。

本文由作者按照 CC BY 4.0 进行授权

热门标签