在topic接收方,有一个比较重要的概念,就是回调(CallBack),回调就是预先给 gps_info 话题传来的消息准备一个回调函数,你事先定义好回调函数的操作,本例中是计算到原点的距离。只有当有消息来时,回调函数才会被触发执行。具体去触发的命令就是 ros::spin() ,它会反复的查看有没有消息来,如果有就会让回调函数去处理。
但是,千万不要认为,只要指定了回调函数,系统就回去自动触发,你必须 ros::spin() 或者 ros::spinOnce() 才能真正使回调函数生效。
Listener.cpp
#include <ros/ros.h>
#include <topic_demo/gps.h>
#include <std_msgs/Float32.h>
void gpsCallback(const topic_demo::gps::ConstPtr &msg)
{
std_msgs::Float32 distance; //计算离原点(0,0)的距离
//建议使用ROS原生的float类型
distance.data = sqrt(pow(msg->x,2)+pow(msg->y,2));
ROS_INFO("Listener: Distance to origin = %f, state: %s",distance.data,msg->state.c
_str()); //输出
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("gps_info", 1, gpsCallback); //设置回调函数gpsCallback
//三个参数:1.监听topic 2、队列长度 3、指针:指向处理这个消息的回调函数。
ros::spin(); //ros::spin()用于调用所有可触发的回调函数,将进入循环,不会返回,类似于在循环里反复
调用spinOnce()
//而ros::spinOnce()只会去触发一次
return 0;
}
CmakeLisrs.txt文件修改
在CMakeLists.txt添加以下内容,生成可执行文件。
add_executable(talker src/talker.cpp) #生成可执行文件talker
add_dependencies(talker topic_demo_generate_messages_cpp)
#表明在编译talker前,必须先生编译完成自定义消息
#必须添加add_dependencies,否则找不到自定义的msg产生的头文件
#表明在编译talker前,必须先生编译完成自定义消息
target_link_libraries(talker ${catkin_LIBRARIES}) #链接
add_executable(listener src/listener.cpp ) #声称可执行文件listener
add_dependencies(listener topic_demo_generate_messages_cpp)
target_link_libraries(listener ${catkin_LIBRARIES})#链接
扩展:回调函数与spin()方法
回调函数在编程中是一种重要的 方法,在维基百科上的解释是:
In computer programming, a callback is any executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at a given time.
回调函数作为参数被传入到了另一个函数中(在本例中传递的是函数指针),在未来某个时刻(当有新的message到达),就会立即执行。Subscriber接收到消息,实际上是先把消息放到一个队列中去,如图所示。队列的长度在Subscriber构建的时候设置好了。当有spin函数执行,就会去处理消息队列中队首的消息。
1.png
spin具体处理的方法又可分为阻塞/非阻塞,单线程/多线程,在ROS函数接口层面我们有4种spin的方式:
编译、执行
catkin_make\rosrun
网友评论