如下均是我的在實際耕碼的過程當中遇到的問題和整理的結果,可能會有不對的地方,望各位指正與交流c++
-------------------------------------------------我會有喵的---------------------------------------------------緩存
c++中的回調函數:dom
A "callback" is any function that is called by another function which takes the first function as a parameter.函數
直白點說,就是「函數#"的參數是另外一個函數,經過「函數#"調用另外一個函數,這個另外一個函數就是回調函數。以數學形式來看(雖然不太恰當):Function(y)和g(x)。Function(y)是一個函數,g(x)也是一個函數,那麼Function(g(x))就能夠當作是一個回調過程,g(x)就是回調函數。線程
更直接地說,咱們通常都是調用opencv裏面的庫函數,如今關係反過來了,咱們要讓opencv調用一個咱們本身寫的函數,這個過程就是回調。那個被opencv調用的(咱們本身寫的)函數就是回調函數。接下來舉例規範地說一下:code
不帶參數的回調函數:回調函數
//回調函數 void wordsCallback() { std::cout<<"Hello World!"<<std::endl; } //實現回調函數的"調用函數" void wods(void (*callfuction)()) { callfuction(); } int main(int argc,char* argv[]) { words(wodsCallback); return 0; } 程序的正確輸出結果是:Hello World!
帶參數的回調函數:數學
//回調函數 void wordsCallback(char* s) { std::cout<<s<<std::endl; } //實現帶參回調函數的"調用函數" void words(void (*callfuction)(char*),char* s) { callfuction(s); } int main(int argc,char* argv[]) { words(wordsCallback,"Hello World!"); return 0; } 程序的正確輸出結果:Hello World!
接下來咱們看看ROS中的回調函數。通常來講這個回調函數會用一些比較顯著且比較統一的名字:**Callback(如ScanCallback/CameraCallback),它是在訂閱話題的時候使用的。因此在使用時,咱們須要聲明訂閱話題的名稱,而後選擇話題,最後調用Callback函數。廢話很少說,舉個例子(忽然想吃舉個栗子了啊-------):io
ros::Subscriber sub_raw_image = n.subscribe(IMAGE_TOPIC, 2000, imageCallback);
先聲明訂閱的話題的名稱:opencv
sub_raw_image
而後,選擇咱們須要訂閱的話題。
IMAGE_TOPIC
題外話,ROS中有不少話題,你能夠本身寫,上面這個IMAGE_TOIC就是我本身寫的。固然你也可使用一些系統提供的。好比你啓動了激光雷達,不管是仿真Gazebo中的仍是真的激光雷達(如rplidar),那你就能夠訂閱「/scan」這個話題。
2000表明咱們一次性能夠緩存多少消息(暫時沒發現這個數字對個人程序會帶來很大的影響,我常常寫成1),最後那個就是回調函數了。
imageCallback
對於imageCallback的實現須要說一下。ROS中,imageCallback的參數是與你的話題息息相關的,你要跟據訂閱的話題來肯定參數。通常來講,程序的主要功能也都是在回調函數中實現的。你須要的數據,都是要經過話題訂閱的,而訂閱了就確定有回調函數。你能夠把一個個回調函數當作是一個個單獨的線程。只要你訂閱的消息一更新,回調函數就會被調用,對新的數據進行處理,程序就這麼不斷的進行下去了。這裏咱們仍舊舉例:
void forwardCallback(const nav_msgs::Odometry::ConstPtr &forward_msg){} void imageCallback(const sensor_msgs::ImageConstPtr &image_msg){}
須要肯定的就是這個sensor_msgs::ImageConstPtr和nav_msgs::Odometry::ConstPtr啦!
嗯啊,今天到此結束啦,白白!