In the previous article, we achieved the first ROS program - Publisher (publisher), but we also note that in the last article, even though our program is very small, but they occupy a lot of CPU resources .
This is because the publisher while
did not perform the necessary cycles in sleep
operation so that the publisher has been running at the highest rate, prolonged occupation of CPU.
This article is divided into two parts:
- Adding publisher in
sleep
the frequency of calling the publisher's stable at 1Hz - Achieve a subscriber (Subscriber)
1. The publisher addedsleep
In fact, only two lines of work we need to do, first of all create an ros::Rate
object, and while
the object of calling the cycle in .sleep()
function can be.
After complete code modified as follows:
#include <ros/ros.h>
#include <std_msgs/Float64.h>
int main(int argc, char **argv) {
ros::init(argc, argv, "minimal_publisher"); // 初始化节点名
ros::NodeHandle n; //
// ++++
ros::Rate s_timer(1.0); // 参数1.0代表发布频率即1.0Hz
// ++++
ros::Publisher my_publisher_object = n.advertise<std_msgs::Float64>("topic1", 1); // 创建一个发布器,调用advertise通知ROS Master话题名称以及话题类型
//"topic1" 是话题名
// 参数 "1" 是queue_size,表示缓冲区大小
std_msgs::Float64 input_float; // 创建一个发布器将要使用的消息变量
// 该消息定义在: /opt/ros/indigo/share/std_msgs
// 在ROS中发布的消息都应该提前定义,以便订阅者接收到消息后该如何解读
// Float64消息的定义如下,其中包含一个数据字段data:
// float64 data
input_float.data = 0.0; // 设置数据字段
// 程序所要做的工作将在下面的循环里完成
while (ros::ok())
{
// 该循环没有sleep,因此将一直处于运行状态,不断消耗CPU资源
input_float.data = input_float.data + 0.001; //每循环一次+0.01
my_publisher_object.publish(input_float); // 发布消息到对应的话题
// ++++
s_timer.sleep(); // 在这里调用sleep函数可以让程序在这里
// 停止一段时间以便达到要求的发布频率
// ++++
}
}
The modified release re-compile, and will run in and the last article as:
roscore
Then open a terminal run
rosrun my_minimal_node my_minimal_publisher # 启动发布器
Check the release frequency, running
rostopic hz /topic1
At this point you can see the frequency of publication publisher has been basically stable at 1Hz
a. The system then checks the status of the monitor:
The same can be seen at this time the CPU occupancy rate has come down.
2. Implement a subscriber
First, we will advance the edited copy the code to the subscriber src
directory, as follows:
#include<ros/ros.h>
#include<std_msgs/Float64.h>
void myCallback(const std_msgs::Float64& message_holder)
{
// 打印出我们接收到的值
ROS_INFO("received value is: %f",message_holder.data);
}
int main(int argc, char **argv)
{
ros::init(argc,argv,"minimal_subscriber"); //初始化节点
// 节点名定义为 minimal_subscriber
ros::NodeHandle n; // 节点句柄,用来创建订阅器
// 订阅话题'topic1'
// subscribe中的mycallback是回调函数,每当有新数据到来时,该函数
// 便会被调用
// 实际的工作是在回调函数中完成的
ros::Subscriber my_subscriber_object=
n.subscribe("topic1",1,myCallback);
ros::spin(); // 类似于 `while(1)`语句,但是当有新消息到来时,会调用回调函数
return 0;
}
And then on the same article, just write to compile our subscriber, we also need to modify CMakeLists.txt
the file in order to let the compiler know that we should compile the new file. Analogy on the publisher's articles, we CMakeLists.txt
add the following two lines in the file:
add_executable(my_minimal_subscriber src/minimal_subscriber .cpp) # 第一个参数是生成后的可执行文件名 第二个参数
# 是源文件路径名
target_link_libraries(my_minimal_subscriber ${catkin_LIBRARIES}) # 链接库
Open a terminal, navigate to the working directory ~/catkin_ws
, and then execute the command
catkin_make
After waiting for compiled sequentially execute the command (these commands are input at different terminals)
roscore
rosrun my_minimal_node my_minimal_publisher
rosrun my_minimal_node my_minimal_subscriber
Then the subscriber terminal can be seen in the output
Run command rosnode list
check node
Finally, you can run the command
rqt_graph
Displaying a graphical nodes - connected FIG topic:
As can be seen from the above visual display of the message flow from the publisher to the topic topic1
and then flows to the subscriber.
video
ROS write your first subscription program
All of the above process I recorded a video, in the process of browsing the article if you have problems, you can view the video to see how I was doing.