C++中的回调函数:
A “callback” is any function that is called by another function which takes the first function as a parameter.
直白点说,就是“函数#”的参数是另一个函数,通过“函数#”调用另一个函数,这个“函数#”就是回调函数。以数学形式来看(虽然不太恰当):Function(y)和Function(g(x))。Function(y)是一个函数,g(x)也是一个函数,那么Function(g(x))就可以看成是一个回调过程,g(x)就是回调函数。
更直接地说,我们一般都是调用OpenCV里面的库函数,现在关系反过来了,我们要让OpenCV调用一个我们自己写的函数,这个过程就是回调。那个被OpenCV调用的(我们自己写的)函数就是回调函数。接下來举例规范地说一下:
不带参数的回调函数:
1 | //回调函数 |
带参数的回调函数:
1 | //回调函数 |
ROS中的回调函数
一般来说这个回调函数会用一些比较显著且比较统一的名字:**Callback(如ScanCallback/CameraCallback),它是在订阅话题的时候使用的。所以在使用时,我们需要声明订阅话题的名称,然后选择话题,最后调用Callback函数。)
举个栗子:
1 | void imageCallback(const sensor_msgs::ImageConstPtr& msg) |
1 | image_transport::Subscriber sub_raw_image = it.subscribe("camera/rgb/image_raw", 1, imageCallback); |
先声明订阅的话题的名称:
1 | sub_raw_image |
然后,选择我们需要订阅的话题。
1 | "camera/rgb/image_raw" |
题外话,ROS中有很多话题,有的是自己写的,有的来自其他节点发布的。
1
代表我们一次性可以缓存多少消息,最后那个就是回调函数了。
1 | imageCallback |
ROS中,imageCallback的参数是与话题息息相关的,要跟据订阅的话题来确定参数。
一般来说,程序的主要功能也都是在回调函数中实现的。
或者说,将来自【订阅话题】中的数据,传递给【目标函数】进行处理。
需要的数据,都是要通过话题订阅的,而订阅了就肯定有回调函数。可以把一个个回调函数看成是一个个单独的线程。
只要订阅的消息一更新(当有消息到达topic时),回调函数就会被调用(ROS就会调用imageCallback ()函数),对新的(到达的)数据进行处理,程序就这么不断的进行下去了。
这里我们仍旧举例:
1 | void forwardCallback(const nav_msgs::Odometry::ConstPtr &forward_msg){} |
需要确定的就是这个sensor_msgs::ImageConstPtr
和nav_msgs::Odometry::ConstPtr
.
使用类作为回调函数:
举个栗子:
1 | class Listener |
1 | Listener listen; |
如果订阅在Listener内部,你替换最后的参数为关键词this,它意味着订阅会引用类的一部分。
以上!
附:
&
有 “引用” 和 “ 取地址”的含义
int a; int &b = a;
上述两行语句执行完之后,a、b表示同一个变量,对其中一个的操作相当于对另一个的操作。
int a; int *b = &a;
则b中储存的是a的地址。对*b
的任何操作相当于对a
的操作。